#
tokens: 46856/50000 2/808 files (page 88/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 88 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/pip/_vendor/requests/adapters.py:
--------------------------------------------------------------------------------

```python
  1 | """
  2 | requests.adapters
  3 | ~~~~~~~~~~~~~~~~~
  4 | 
  5 | This module contains the transport adapters that Requests uses to define
  6 | and maintain connections.
  7 | """
  8 | 
  9 | import os.path
 10 | import socket  # noqa: F401
 11 | import typing
 12 | import warnings
 13 | 
 14 | from pip._vendor.urllib3.exceptions import ClosedPoolError, ConnectTimeoutError
 15 | from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError
 16 | from pip._vendor.urllib3.exceptions import InvalidHeader as _InvalidHeader
 17 | from pip._vendor.urllib3.exceptions import (
 18 |     LocationValueError,
 19 |     MaxRetryError,
 20 |     NewConnectionError,
 21 |     ProtocolError,
 22 | )
 23 | from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError
 24 | from pip._vendor.urllib3.exceptions import ReadTimeoutError, ResponseError
 25 | from pip._vendor.urllib3.exceptions import SSLError as _SSLError
 26 | from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url
 27 | from pip._vendor.urllib3.util import Timeout as TimeoutSauce
 28 | from pip._vendor.urllib3.util import parse_url
 29 | from pip._vendor.urllib3.util.retry import Retry
 30 | from pip._vendor.urllib3.util.ssl_ import create_urllib3_context
 31 | 
 32 | from .auth import _basic_auth_str
 33 | from .compat import basestring, urlparse
 34 | from .cookies import extract_cookies_to_jar
 35 | from .exceptions import (
 36 |     ConnectionError,
 37 |     ConnectTimeout,
 38 |     InvalidHeader,
 39 |     InvalidProxyURL,
 40 |     InvalidSchema,
 41 |     InvalidURL,
 42 |     ProxyError,
 43 |     ReadTimeout,
 44 |     RetryError,
 45 |     SSLError,
 46 | )
 47 | from .models import Response
 48 | from .structures import CaseInsensitiveDict
 49 | from .utils import (
 50 |     DEFAULT_CA_BUNDLE_PATH,
 51 |     extract_zipped_paths,
 52 |     get_auth_from_url,
 53 |     get_encoding_from_headers,
 54 |     prepend_scheme_if_needed,
 55 |     select_proxy,
 56 |     urldefragauth,
 57 | )
 58 | 
 59 | try:
 60 |     from pip._vendor.urllib3.contrib.socks import SOCKSProxyManager
 61 | except ImportError:
 62 | 
 63 |     def SOCKSProxyManager(*args, **kwargs):
 64 |         raise InvalidSchema("Missing dependencies for SOCKS support.")
 65 | 
 66 | 
 67 | if typing.TYPE_CHECKING:
 68 |     from .models import PreparedRequest
 69 | 
 70 | 
 71 | DEFAULT_POOLBLOCK = False
 72 | DEFAULT_POOLSIZE = 10
 73 | DEFAULT_RETRIES = 0
 74 | DEFAULT_POOL_TIMEOUT = None
 75 | 
 76 | 
 77 | try:
 78 |     import ssl  # noqa: F401
 79 | 
 80 |     _preloaded_ssl_context = create_urllib3_context()
 81 |     _preloaded_ssl_context.load_verify_locations(
 82 |         extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
 83 |     )
 84 | except ImportError:
 85 |     # Bypass default SSLContext creation when Python
 86 |     # interpreter isn't built with the ssl module.
 87 |     _preloaded_ssl_context = None
 88 | 
 89 | 
 90 | def _urllib3_request_context(
 91 |     request: "PreparedRequest",
 92 |     verify: "bool | str | None",
 93 |     client_cert: "typing.Tuple[str, str] | str | None",
 94 |     poolmanager: "PoolManager",
 95 | ) -> "(typing.Dict[str, typing.Any], typing.Dict[str, typing.Any])":
 96 |     host_params = {}
 97 |     pool_kwargs = {}
 98 |     parsed_request_url = urlparse(request.url)
 99 |     scheme = parsed_request_url.scheme.lower()
100 |     port = parsed_request_url.port
101 | 
102 |     # Determine if we have and should use our default SSLContext
103 |     # to optimize performance on standard requests.
104 |     poolmanager_kwargs = getattr(poolmanager, "connection_pool_kw", {})
105 |     has_poolmanager_ssl_context = poolmanager_kwargs.get("ssl_context")
106 |     should_use_default_ssl_context = (
107 |         _preloaded_ssl_context is not None and not has_poolmanager_ssl_context
108 |     )
109 | 
110 |     cert_reqs = "CERT_REQUIRED"
111 |     if verify is False:
112 |         cert_reqs = "CERT_NONE"
113 |     elif verify is True and should_use_default_ssl_context:
114 |         pool_kwargs["ssl_context"] = _preloaded_ssl_context
115 |     elif isinstance(verify, str):
116 |         if not os.path.isdir(verify):
117 |             pool_kwargs["ca_certs"] = verify
118 |         else:
119 |             pool_kwargs["ca_cert_dir"] = verify
120 |     pool_kwargs["cert_reqs"] = cert_reqs
121 |     if client_cert is not None:
122 |         if isinstance(client_cert, tuple) and len(client_cert) == 2:
123 |             pool_kwargs["cert_file"] = client_cert[0]
124 |             pool_kwargs["key_file"] = client_cert[1]
125 |         else:
126 |             # According to our docs, we allow users to specify just the client
127 |             # cert path
128 |             pool_kwargs["cert_file"] = client_cert
129 |     host_params = {
130 |         "scheme": scheme,
131 |         "host": parsed_request_url.hostname,
132 |         "port": port,
133 |     }
134 |     return host_params, pool_kwargs
135 | 
136 | 
137 | class BaseAdapter:
138 |     """The Base Transport Adapter"""
139 | 
140 |     def __init__(self):
141 |         super().__init__()
142 | 
143 |     def send(
144 |         self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
145 |     ):
146 |         """Sends PreparedRequest object. Returns Response object.
147 | 
148 |         :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
149 |         :param stream: (optional) Whether to stream the request content.
150 |         :param timeout: (optional) How long to wait for the server to send
151 |             data before giving up, as a float, or a :ref:`(connect timeout,
152 |             read timeout) <timeouts>` tuple.
153 |         :type timeout: float or tuple
154 |         :param verify: (optional) Either a boolean, in which case it controls whether we verify
155 |             the server's TLS certificate, or a string, in which case it must be a path
156 |             to a CA bundle to use
157 |         :param cert: (optional) Any user-provided SSL certificate to be trusted.
158 |         :param proxies: (optional) The proxies dictionary to apply to the request.
159 |         """
160 |         raise NotImplementedError
161 | 
162 |     def close(self):
163 |         """Cleans up adapter specific items."""
164 |         raise NotImplementedError
165 | 
166 | 
167 | class HTTPAdapter(BaseAdapter):
168 |     """The built-in HTTP Adapter for urllib3.
169 | 
170 |     Provides a general-case interface for Requests sessions to contact HTTP and
171 |     HTTPS urls by implementing the Transport Adapter interface. This class will
172 |     usually be created by the :class:`Session <Session>` class under the
173 |     covers.
174 | 
175 |     :param pool_connections: The number of urllib3 connection pools to cache.
176 |     :param pool_maxsize: The maximum number of connections to save in the pool.
177 |     :param max_retries: The maximum number of retries each connection
178 |         should attempt. Note, this applies only to failed DNS lookups, socket
179 |         connections and connection timeouts, never to requests where data has
180 |         made it to the server. By default, Requests does not retry failed
181 |         connections. If you need granular control over the conditions under
182 |         which we retry a request, import urllib3's ``Retry`` class and pass
183 |         that instead.
184 |     :param pool_block: Whether the connection pool should block for connections.
185 | 
186 |     Usage::
187 | 
188 |       >>> import requests
189 |       >>> s = requests.Session()
190 |       >>> a = requests.adapters.HTTPAdapter(max_retries=3)
191 |       >>> s.mount('http://', a)
192 |     """
193 | 
194 |     __attrs__ = [
195 |         "max_retries",
196 |         "config",
197 |         "_pool_connections",
198 |         "_pool_maxsize",
199 |         "_pool_block",
200 |     ]
201 | 
202 |     def __init__(
203 |         self,
204 |         pool_connections=DEFAULT_POOLSIZE,
205 |         pool_maxsize=DEFAULT_POOLSIZE,
206 |         max_retries=DEFAULT_RETRIES,
207 |         pool_block=DEFAULT_POOLBLOCK,
208 |     ):
209 |         if max_retries == DEFAULT_RETRIES:
210 |             self.max_retries = Retry(0, read=False)
211 |         else:
212 |             self.max_retries = Retry.from_int(max_retries)
213 |         self.config = {}
214 |         self.proxy_manager = {}
215 | 
216 |         super().__init__()
217 | 
218 |         self._pool_connections = pool_connections
219 |         self._pool_maxsize = pool_maxsize
220 |         self._pool_block = pool_block
221 | 
222 |         self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
223 | 
224 |     def __getstate__(self):
225 |         return {attr: getattr(self, attr, None) for attr in self.__attrs__}
226 | 
227 |     def __setstate__(self, state):
228 |         # Can't handle by adding 'proxy_manager' to self.__attrs__ because
229 |         # self.poolmanager uses a lambda function, which isn't pickleable.
230 |         self.proxy_manager = {}
231 |         self.config = {}
232 | 
233 |         for attr, value in state.items():
234 |             setattr(self, attr, value)
235 | 
236 |         self.init_poolmanager(
237 |             self._pool_connections, self._pool_maxsize, block=self._pool_block
238 |         )
239 | 
240 |     def init_poolmanager(
241 |         self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs
242 |     ):
243 |         """Initializes a urllib3 PoolManager.
244 | 
245 |         This method should not be called from user code, and is only
246 |         exposed for use when subclassing the
247 |         :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
248 | 
249 |         :param connections: The number of urllib3 connection pools to cache.
250 |         :param maxsize: The maximum number of connections to save in the pool.
251 |         :param block: Block when no free connections are available.
252 |         :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
253 |         """
254 |         # save these values for pickling
255 |         self._pool_connections = connections
256 |         self._pool_maxsize = maxsize
257 |         self._pool_block = block
258 | 
259 |         self.poolmanager = PoolManager(
260 |             num_pools=connections,
261 |             maxsize=maxsize,
262 |             block=block,
263 |             **pool_kwargs,
264 |         )
265 | 
266 |     def proxy_manager_for(self, proxy, **proxy_kwargs):
267 |         """Return urllib3 ProxyManager for the given proxy.
268 | 
269 |         This method should not be called from user code, and is only
270 |         exposed for use when subclassing the
271 |         :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
272 | 
273 |         :param proxy: The proxy to return a urllib3 ProxyManager for.
274 |         :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
275 |         :returns: ProxyManager
276 |         :rtype: urllib3.ProxyManager
277 |         """
278 |         if proxy in self.proxy_manager:
279 |             manager = self.proxy_manager[proxy]
280 |         elif proxy.lower().startswith("socks"):
281 |             username, password = get_auth_from_url(proxy)
282 |             manager = self.proxy_manager[proxy] = SOCKSProxyManager(
283 |                 proxy,
284 |                 username=username,
285 |                 password=password,
286 |                 num_pools=self._pool_connections,
287 |                 maxsize=self._pool_maxsize,
288 |                 block=self._pool_block,
289 |                 **proxy_kwargs,
290 |             )
291 |         else:
292 |             proxy_headers = self.proxy_headers(proxy)
293 |             manager = self.proxy_manager[proxy] = proxy_from_url(
294 |                 proxy,
295 |                 proxy_headers=proxy_headers,
296 |                 num_pools=self._pool_connections,
297 |                 maxsize=self._pool_maxsize,
298 |                 block=self._pool_block,
299 |                 **proxy_kwargs,
300 |             )
301 | 
302 |         return manager
303 | 
304 |     def cert_verify(self, conn, url, verify, cert):
305 |         """Verify a SSL certificate. This method should not be called from user
306 |         code, and is only exposed for use when subclassing the
307 |         :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
308 | 
309 |         :param conn: The urllib3 connection object associated with the cert.
310 |         :param url: The requested URL.
311 |         :param verify: Either a boolean, in which case it controls whether we verify
312 |             the server's TLS certificate, or a string, in which case it must be a path
313 |             to a CA bundle to use
314 |         :param cert: The SSL certificate to verify.
315 |         """
316 |         if url.lower().startswith("https") and verify:
317 |             conn.cert_reqs = "CERT_REQUIRED"
318 | 
319 |             # Only load the CA certificates if 'verify' is a string indicating the CA bundle to use.
320 |             # Otherwise, if verify is a boolean, we don't load anything since
321 |             # the connection will be using a context with the default certificates already loaded,
322 |             # and this avoids a call to the slow load_verify_locations()
323 |             if verify is not True:
324 |                 # `verify` must be a str with a path then
325 |                 cert_loc = verify
326 | 
327 |                 if not os.path.exists(cert_loc):
328 |                     raise OSError(
329 |                         f"Could not find a suitable TLS CA certificate bundle, "
330 |                         f"invalid path: {cert_loc}"
331 |                     )
332 | 
333 |                 if not os.path.isdir(cert_loc):
334 |                     conn.ca_certs = cert_loc
335 |                 else:
336 |                     conn.ca_cert_dir = cert_loc
337 |         else:
338 |             conn.cert_reqs = "CERT_NONE"
339 |             conn.ca_certs = None
340 |             conn.ca_cert_dir = None
341 | 
342 |         if cert:
343 |             if not isinstance(cert, basestring):
344 |                 conn.cert_file = cert[0]
345 |                 conn.key_file = cert[1]
346 |             else:
347 |                 conn.cert_file = cert
348 |                 conn.key_file = None
349 |             if conn.cert_file and not os.path.exists(conn.cert_file):
350 |                 raise OSError(
351 |                     f"Could not find the TLS certificate file, "
352 |                     f"invalid path: {conn.cert_file}"
353 |                 )
354 |             if conn.key_file and not os.path.exists(conn.key_file):
355 |                 raise OSError(
356 |                     f"Could not find the TLS key file, invalid path: {conn.key_file}"
357 |                 )
358 | 
359 |     def build_response(self, req, resp):
360 |         """Builds a :class:`Response <requests.Response>` object from a urllib3
361 |         response. This should not be called from user code, and is only exposed
362 |         for use when subclassing the
363 |         :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`
364 | 
365 |         :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.
366 |         :param resp: The urllib3 response object.
367 |         :rtype: requests.Response
368 |         """
369 |         response = Response()
370 | 
371 |         # Fallback to None if there's no status_code, for whatever reason.
372 |         response.status_code = getattr(resp, "status", None)
373 | 
374 |         # Make headers case-insensitive.
375 |         response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
376 | 
377 |         # Set encoding.
378 |         response.encoding = get_encoding_from_headers(response.headers)
379 |         response.raw = resp
380 |         response.reason = response.raw.reason
381 | 
382 |         if isinstance(req.url, bytes):
383 |             response.url = req.url.decode("utf-8")
384 |         else:
385 |             response.url = req.url
386 | 
387 |         # Add new cookies from the server.
388 |         extract_cookies_to_jar(response.cookies, req, resp)
389 | 
390 |         # Give the Response some context.
391 |         response.request = req
392 |         response.connection = self
393 | 
394 |         return response
395 | 
396 |     def build_connection_pool_key_attributes(self, request, verify, cert=None):
397 |         """Build the PoolKey attributes used by urllib3 to return a connection.
398 | 
399 |         This looks at the PreparedRequest, the user-specified verify value,
400 |         and the value of the cert parameter to determine what PoolKey values
401 |         to use to select a connection from a given urllib3 Connection Pool.
402 | 
403 |         The SSL related pool key arguments are not consistently set. As of
404 |         this writing, use the following to determine what keys may be in that
405 |         dictionary:
406 | 
407 |         * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the
408 |           default Requests SSL Context
409 |         * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but
410 |           ``"cert_reqs"`` will be set
411 |         * If ``verify`` is a string, (i.e., it is a user-specified trust bundle)
412 |           ``"ca_certs"`` will be set if the string is not a directory recognized
413 |           by :py:func:`os.path.isdir`, otherwise ``"ca_certs_dir"`` will be
414 |           set.
415 |         * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If
416 |           ``"cert"`` is a tuple with a second item, ``"key_file"`` will also
417 |           be present
418 | 
419 |         To override these settings, one may subclass this class, call this
420 |         method and use the above logic to change parameters as desired. For
421 |         example, if one wishes to use a custom :py:class:`ssl.SSLContext` one
422 |         must both set ``"ssl_context"`` and based on what else they require,
423 |         alter the other keys to ensure the desired behaviour.
424 | 
425 |         :param request:
426 |             The PreparedReqest being sent over the connection.
427 |         :type request:
428 |             :class:`~requests.models.PreparedRequest`
429 |         :param verify:
430 |             Either a boolean, in which case it controls whether
431 |             we verify the server's TLS certificate, or a string, in which case it
432 |             must be a path to a CA bundle to use.
433 |         :param cert:
434 |             (optional) Any user-provided SSL certificate for client
435 |             authentication (a.k.a., mTLS). This may be a string (i.e., just
436 |             the path to a file which holds both certificate and key) or a
437 |             tuple of length 2 with the certificate file path and key file
438 |             path.
439 |         :returns:
440 |             A tuple of two dictionaries. The first is the "host parameters"
441 |             portion of the Pool Key including scheme, hostname, and port. The
442 |             second is a dictionary of SSLContext related parameters.
443 |         """
444 |         return _urllib3_request_context(request, verify, cert, self.poolmanager)
445 | 
446 |     def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None):
447 |         """Returns a urllib3 connection for the given request and TLS settings.
448 |         This should not be called from user code, and is only exposed for use
449 |         when subclassing the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
450 | 
451 |         :param request:
452 |             The :class:`PreparedRequest <PreparedRequest>` object to be sent
453 |             over the connection.
454 |         :param verify:
455 |             Either a boolean, in which case it controls whether we verify the
456 |             server's TLS certificate, or a string, in which case it must be a
457 |             path to a CA bundle to use.
458 |         :param proxies:
459 |             (optional) The proxies dictionary to apply to the request.
460 |         :param cert:
461 |             (optional) Any user-provided SSL certificate to be used for client
462 |             authentication (a.k.a., mTLS).
463 |         :rtype:
464 |             urllib3.ConnectionPool
465 |         """
466 |         proxy = select_proxy(request.url, proxies)
467 |         try:
468 |             host_params, pool_kwargs = self.build_connection_pool_key_attributes(
469 |                 request,
470 |                 verify,
471 |                 cert,
472 |             )
473 |         except ValueError as e:
474 |             raise InvalidURL(e, request=request)
475 |         if proxy:
476 |             proxy = prepend_scheme_if_needed(proxy, "http")
477 |             proxy_url = parse_url(proxy)
478 |             if not proxy_url.host:
479 |                 raise InvalidProxyURL(
480 |                     "Please check proxy URL. It is malformed "
481 |                     "and could be missing the host."
482 |                 )
483 |             proxy_manager = self.proxy_manager_for(proxy)
484 |             conn = proxy_manager.connection_from_host(
485 |                 **host_params, pool_kwargs=pool_kwargs
486 |             )
487 |         else:
488 |             # Only scheme should be lower case
489 |             conn = self.poolmanager.connection_from_host(
490 |                 **host_params, pool_kwargs=pool_kwargs
491 |             )
492 | 
493 |         return conn
494 | 
495 |     def get_connection(self, url, proxies=None):
496 |         """DEPRECATED: Users should move to `get_connection_with_tls_context`
497 |         for all subclasses of HTTPAdapter using Requests>=2.32.2.
498 | 
499 |         Returns a urllib3 connection for the given URL. This should not be
500 |         called from user code, and is only exposed for use when subclassing the
501 |         :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
502 | 
503 |         :param url: The URL to connect to.
504 |         :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
505 |         :rtype: urllib3.ConnectionPool
506 |         """
507 |         warnings.warn(
508 |             (
509 |                 "`get_connection` has been deprecated in favor of "
510 |                 "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses "
511 |                 "will need to migrate for Requests>=2.32.2. Please see "
512 |                 "https://github.com/psf/requests/pull/6710 for more details."
513 |             ),
514 |             DeprecationWarning,
515 |         )
516 |         proxy = select_proxy(url, proxies)
517 | 
518 |         if proxy:
519 |             proxy = prepend_scheme_if_needed(proxy, "http")
520 |             proxy_url = parse_url(proxy)
521 |             if not proxy_url.host:
522 |                 raise InvalidProxyURL(
523 |                     "Please check proxy URL. It is malformed "
524 |                     "and could be missing the host."
525 |                 )
526 |             proxy_manager = self.proxy_manager_for(proxy)
527 |             conn = proxy_manager.connection_from_url(url)
528 |         else:
529 |             # Only scheme should be lower case
530 |             parsed = urlparse(url)
531 |             url = parsed.geturl()
532 |             conn = self.poolmanager.connection_from_url(url)
533 | 
534 |         return conn
535 | 
536 |     def close(self):
537 |         """Disposes of any internal state.
538 | 
539 |         Currently, this closes the PoolManager and any active ProxyManager,
540 |         which closes any pooled connections.
541 |         """
542 |         self.poolmanager.clear()
543 |         for proxy in self.proxy_manager.values():
544 |             proxy.clear()
545 | 
546 |     def request_url(self, request, proxies):
547 |         """Obtain the url to use when making the final request.
548 | 
549 |         If the message is being sent through a HTTP proxy, the full URL has to
550 |         be used. Otherwise, we should only use the path portion of the URL.
551 | 
552 |         This should not be called from user code, and is only exposed for use
553 |         when subclassing the
554 |         :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
555 | 
556 |         :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
557 |         :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
558 |         :rtype: str
559 |         """
560 |         proxy = select_proxy(request.url, proxies)
561 |         scheme = urlparse(request.url).scheme
562 | 
563 |         is_proxied_http_request = proxy and scheme != "https"
564 |         using_socks_proxy = False
565 |         if proxy:
566 |             proxy_scheme = urlparse(proxy).scheme.lower()
567 |             using_socks_proxy = proxy_scheme.startswith("socks")
568 | 
569 |         url = request.path_url
570 |         if url.startswith("//"):  # Don't confuse urllib3
571 |             url = f"/{url.lstrip('/')}"
572 | 
573 |         if is_proxied_http_request and not using_socks_proxy:
574 |             url = urldefragauth(request.url)
575 | 
576 |         return url
577 | 
578 |     def add_headers(self, request, **kwargs):
579 |         """Add any headers needed by the connection. As of v2.0 this does
580 |         nothing by default, but is left for overriding by users that subclass
581 |         the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
582 | 
583 |         This should not be called from user code, and is only exposed for use
584 |         when subclassing the
585 |         :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
586 | 
587 |         :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to.
588 |         :param kwargs: The keyword arguments from the call to send().
589 |         """
590 |         pass
591 | 
592 |     def proxy_headers(self, proxy):
593 |         """Returns a dictionary of the headers to add to any request sent
594 |         through a proxy. This works with urllib3 magic to ensure that they are
595 |         correctly sent to the proxy, rather than in a tunnelled request if
596 |         CONNECT is being used.
597 | 
598 |         This should not be called from user code, and is only exposed for use
599 |         when subclassing the
600 |         :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
601 | 
602 |         :param proxy: The url of the proxy being used for this request.
603 |         :rtype: dict
604 |         """
605 |         headers = {}
606 |         username, password = get_auth_from_url(proxy)
607 | 
608 |         if username:
609 |             headers["Proxy-Authorization"] = _basic_auth_str(username, password)
610 | 
611 |         return headers
612 | 
613 |     def send(
614 |         self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
615 |     ):
616 |         """Sends PreparedRequest object. Returns Response object.
617 | 
618 |         :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
619 |         :param stream: (optional) Whether to stream the request content.
620 |         :param timeout: (optional) How long to wait for the server to send
621 |             data before giving up, as a float, or a :ref:`(connect timeout,
622 |             read timeout) <timeouts>` tuple.
623 |         :type timeout: float or tuple or urllib3 Timeout object
624 |         :param verify: (optional) Either a boolean, in which case it controls whether
625 |             we verify the server's TLS certificate, or a string, in which case it
626 |             must be a path to a CA bundle to use
627 |         :param cert: (optional) Any user-provided SSL certificate to be trusted.
628 |         :param proxies: (optional) The proxies dictionary to apply to the request.
629 |         :rtype: requests.Response
630 |         """
631 | 
632 |         try:
633 |             conn = self.get_connection_with_tls_context(
634 |                 request, verify, proxies=proxies, cert=cert
635 |             )
636 |         except LocationValueError as e:
637 |             raise InvalidURL(e, request=request)
638 | 
639 |         self.cert_verify(conn, request.url, verify, cert)
640 |         url = self.request_url(request, proxies)
641 |         self.add_headers(
642 |             request,
643 |             stream=stream,
644 |             timeout=timeout,
645 |             verify=verify,
646 |             cert=cert,
647 |             proxies=proxies,
648 |         )
649 | 
650 |         chunked = not (request.body is None or "Content-Length" in request.headers)
651 | 
652 |         if isinstance(timeout, tuple):
653 |             try:
654 |                 connect, read = timeout
655 |                 timeout = TimeoutSauce(connect=connect, read=read)
656 |             except ValueError:
657 |                 raise ValueError(
658 |                     f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
659 |                     f"or a single float to set both timeouts to the same value."
660 |                 )
661 |         elif isinstance(timeout, TimeoutSauce):
662 |             pass
663 |         else:
664 |             timeout = TimeoutSauce(connect=timeout, read=timeout)
665 | 
666 |         try:
667 |             resp = conn.urlopen(
668 |                 method=request.method,
669 |                 url=url,
670 |                 body=request.body,
671 |                 headers=request.headers,
672 |                 redirect=False,
673 |                 assert_same_host=False,
674 |                 preload_content=False,
675 |                 decode_content=False,
676 |                 retries=self.max_retries,
677 |                 timeout=timeout,
678 |                 chunked=chunked,
679 |             )
680 | 
681 |         except (ProtocolError, OSError) as err:
682 |             raise ConnectionError(err, request=request)
683 | 
684 |         except MaxRetryError as e:
685 |             if isinstance(e.reason, ConnectTimeoutError):
686 |                 # TODO: Remove this in 3.0.0: see #2811
687 |                 if not isinstance(e.reason, NewConnectionError):
688 |                     raise ConnectTimeout(e, request=request)
689 | 
690 |             if isinstance(e.reason, ResponseError):
691 |                 raise RetryError(e, request=request)
692 | 
693 |             if isinstance(e.reason, _ProxyError):
694 |                 raise ProxyError(e, request=request)
695 | 
696 |             if isinstance(e.reason, _SSLError):
697 |                 # This branch is for urllib3 v1.22 and later.
698 |                 raise SSLError(e, request=request)
699 | 
700 |             raise ConnectionError(e, request=request)
701 | 
702 |         except ClosedPoolError as e:
703 |             raise ConnectionError(e, request=request)
704 | 
705 |         except _ProxyError as e:
706 |             raise ProxyError(e)
707 | 
708 |         except (_SSLError, _HTTPError) as e:
709 |             if isinstance(e, _SSLError):
710 |                 # This branch is for urllib3 versions earlier than v1.22
711 |                 raise SSLError(e, request=request)
712 |             elif isinstance(e, ReadTimeoutError):
713 |                 raise ReadTimeout(e, request=request)
714 |             elif isinstance(e, _InvalidHeader):
715 |                 raise InvalidHeader(e, request=request)
716 |             else:
717 |                 raise
718 | 
719 |         return self.build_response(request, resp)
720 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/operations/install/wheel.py:
--------------------------------------------------------------------------------

```python
  1 | """Support for installing and building the "wheel" binary package format.
  2 | """
  3 | 
  4 | import collections
  5 | import compileall
  6 | import contextlib
  7 | import csv
  8 | import importlib
  9 | import logging
 10 | import os.path
 11 | import re
 12 | import shutil
 13 | import sys
 14 | import warnings
 15 | from base64 import urlsafe_b64encode
 16 | from email.message import Message
 17 | from itertools import chain, filterfalse, starmap
 18 | from typing import (
 19 |     IO,
 20 |     TYPE_CHECKING,
 21 |     Any,
 22 |     BinaryIO,
 23 |     Callable,
 24 |     Dict,
 25 |     Generator,
 26 |     Iterable,
 27 |     Iterator,
 28 |     List,
 29 |     NewType,
 30 |     Optional,
 31 |     Protocol,
 32 |     Sequence,
 33 |     Set,
 34 |     Tuple,
 35 |     Union,
 36 |     cast,
 37 | )
 38 | from zipfile import ZipFile, ZipInfo
 39 | 
 40 | from pip._vendor.distlib.scripts import ScriptMaker
 41 | from pip._vendor.distlib.util import get_export_entry
 42 | from pip._vendor.packaging.utils import canonicalize_name
 43 | 
 44 | from pip._internal.exceptions import InstallationError
 45 | from pip._internal.locations import get_major_minor_version
 46 | from pip._internal.metadata import (
 47 |     BaseDistribution,
 48 |     FilesystemWheel,
 49 |     get_wheel_distribution,
 50 | )
 51 | from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl
 52 | from pip._internal.models.scheme import SCHEME_KEYS, Scheme
 53 | from pip._internal.utils.filesystem import adjacent_tmp_file, replace
 54 | from pip._internal.utils.misc import StreamWrapper, ensure_dir, hash_file, partition
 55 | from pip._internal.utils.unpacking import (
 56 |     current_umask,
 57 |     is_within_directory,
 58 |     set_extracted_file_to_default_mode_plus_executable,
 59 |     zip_item_is_executable,
 60 | )
 61 | from pip._internal.utils.wheel import parse_wheel
 62 | 
 63 | if TYPE_CHECKING:
 64 | 
 65 |     class File(Protocol):
 66 |         src_record_path: "RecordPath"
 67 |         dest_path: str
 68 |         changed: bool
 69 | 
 70 |         def save(self) -> None:
 71 |             pass
 72 | 
 73 | 
 74 | logger = logging.getLogger(__name__)
 75 | 
 76 | RecordPath = NewType("RecordPath", str)
 77 | InstalledCSVRow = Tuple[RecordPath, str, Union[int, str]]
 78 | 
 79 | 
 80 | def rehash(path: str, blocksize: int = 1 << 20) -> Tuple[str, str]:
 81 |     """Return (encoded_digest, length) for path using hashlib.sha256()"""
 82 |     h, length = hash_file(path, blocksize)
 83 |     digest = "sha256=" + urlsafe_b64encode(h.digest()).decode("latin1").rstrip("=")
 84 |     return (digest, str(length))
 85 | 
 86 | 
 87 | def csv_io_kwargs(mode: str) -> Dict[str, Any]:
 88 |     """Return keyword arguments to properly open a CSV file
 89 |     in the given mode.
 90 |     """
 91 |     return {"mode": mode, "newline": "", "encoding": "utf-8"}
 92 | 
 93 | 
 94 | def fix_script(path: str) -> bool:
 95 |     """Replace #!python with #!/path/to/python
 96 |     Return True if file was changed.
 97 |     """
 98 |     # XXX RECORD hashes will need to be updated
 99 |     assert os.path.isfile(path)
100 | 
101 |     with open(path, "rb") as script:
102 |         firstline = script.readline()
103 |         if not firstline.startswith(b"#!python"):
104 |             return False
105 |         exename = sys.executable.encode(sys.getfilesystemencoding())
106 |         firstline = b"#!" + exename + os.linesep.encode("ascii")
107 |         rest = script.read()
108 |     with open(path, "wb") as script:
109 |         script.write(firstline)
110 |         script.write(rest)
111 |     return True
112 | 
113 | 
114 | def wheel_root_is_purelib(metadata: Message) -> bool:
115 |     return metadata.get("Root-Is-Purelib", "").lower() == "true"
116 | 
117 | 
118 | def get_entrypoints(dist: BaseDistribution) -> Tuple[Dict[str, str], Dict[str, str]]:
119 |     console_scripts = {}
120 |     gui_scripts = {}
121 |     for entry_point in dist.iter_entry_points():
122 |         if entry_point.group == "console_scripts":
123 |             console_scripts[entry_point.name] = entry_point.value
124 |         elif entry_point.group == "gui_scripts":
125 |             gui_scripts[entry_point.name] = entry_point.value
126 |     return console_scripts, gui_scripts
127 | 
128 | 
129 | def message_about_scripts_not_on_PATH(scripts: Sequence[str]) -> Optional[str]:
130 |     """Determine if any scripts are not on PATH and format a warning.
131 |     Returns a warning message if one or more scripts are not on PATH,
132 |     otherwise None.
133 |     """
134 |     if not scripts:
135 |         return None
136 | 
137 |     # Group scripts by the path they were installed in
138 |     grouped_by_dir: Dict[str, Set[str]] = collections.defaultdict(set)
139 |     for destfile in scripts:
140 |         parent_dir = os.path.dirname(destfile)
141 |         script_name = os.path.basename(destfile)
142 |         grouped_by_dir[parent_dir].add(script_name)
143 | 
144 |     # We don't want to warn for directories that are on PATH.
145 |     not_warn_dirs = [
146 |         os.path.normcase(os.path.normpath(i)).rstrip(os.sep)
147 |         for i in os.environ.get("PATH", "").split(os.pathsep)
148 |     ]
149 |     # If an executable sits with sys.executable, we don't warn for it.
150 |     #     This covers the case of venv invocations without activating the venv.
151 |     not_warn_dirs.append(
152 |         os.path.normcase(os.path.normpath(os.path.dirname(sys.executable)))
153 |     )
154 |     warn_for: Dict[str, Set[str]] = {
155 |         parent_dir: scripts
156 |         for parent_dir, scripts in grouped_by_dir.items()
157 |         if os.path.normcase(os.path.normpath(parent_dir)) not in not_warn_dirs
158 |     }
159 |     if not warn_for:
160 |         return None
161 | 
162 |     # Format a message
163 |     msg_lines = []
164 |     for parent_dir, dir_scripts in warn_for.items():
165 |         sorted_scripts: List[str] = sorted(dir_scripts)
166 |         if len(sorted_scripts) == 1:
167 |             start_text = f"script {sorted_scripts[0]} is"
168 |         else:
169 |             start_text = "scripts {} are".format(
170 |                 ", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1]
171 |             )
172 | 
173 |         msg_lines.append(
174 |             f"The {start_text} installed in '{parent_dir}' which is not on PATH."
175 |         )
176 | 
177 |     last_line_fmt = (
178 |         "Consider adding {} to PATH or, if you prefer "
179 |         "to suppress this warning, use --no-warn-script-location."
180 |     )
181 |     if len(msg_lines) == 1:
182 |         msg_lines.append(last_line_fmt.format("this directory"))
183 |     else:
184 |         msg_lines.append(last_line_fmt.format("these directories"))
185 | 
186 |     # Add a note if any directory starts with ~
187 |     warn_for_tilde = any(
188 |         i[0] == "~" for i in os.environ.get("PATH", "").split(os.pathsep) if i
189 |     )
190 |     if warn_for_tilde:
191 |         tilde_warning_msg = (
192 |             "NOTE: The current PATH contains path(s) starting with `~`, "
193 |             "which may not be expanded by all applications."
194 |         )
195 |         msg_lines.append(tilde_warning_msg)
196 | 
197 |     # Returns the formatted multiline message
198 |     return "\n".join(msg_lines)
199 | 
200 | 
201 | def _normalized_outrows(
202 |     outrows: Iterable[InstalledCSVRow],
203 | ) -> List[Tuple[str, str, str]]:
204 |     """Normalize the given rows of a RECORD file.
205 | 
206 |     Items in each row are converted into str. Rows are then sorted to make
207 |     the value more predictable for tests.
208 | 
209 |     Each row is a 3-tuple (path, hash, size) and corresponds to a record of
210 |     a RECORD file (see PEP 376 and PEP 427 for details).  For the rows
211 |     passed to this function, the size can be an integer as an int or string,
212 |     or the empty string.
213 |     """
214 |     # Normally, there should only be one row per path, in which case the
215 |     # second and third elements don't come into play when sorting.
216 |     # However, in cases in the wild where a path might happen to occur twice,
217 |     # we don't want the sort operation to trigger an error (but still want
218 |     # determinism).  Since the third element can be an int or string, we
219 |     # coerce each element to a string to avoid a TypeError in this case.
220 |     # For additional background, see--
221 |     # https://github.com/pypa/pip/issues/5868
222 |     return sorted(
223 |         (record_path, hash_, str(size)) for record_path, hash_, size in outrows
224 |     )
225 | 
226 | 
227 | def _record_to_fs_path(record_path: RecordPath, lib_dir: str) -> str:
228 |     return os.path.join(lib_dir, record_path)
229 | 
230 | 
231 | def _fs_to_record_path(path: str, lib_dir: str) -> RecordPath:
232 |     # On Windows, do not handle relative paths if they belong to different
233 |     # logical disks
234 |     if os.path.splitdrive(path)[0].lower() == os.path.splitdrive(lib_dir)[0].lower():
235 |         path = os.path.relpath(path, lib_dir)
236 | 
237 |     path = path.replace(os.path.sep, "/")
238 |     return cast("RecordPath", path)
239 | 
240 | 
241 | def get_csv_rows_for_installed(
242 |     old_csv_rows: List[List[str]],
243 |     installed: Dict[RecordPath, RecordPath],
244 |     changed: Set[RecordPath],
245 |     generated: List[str],
246 |     lib_dir: str,
247 | ) -> List[InstalledCSVRow]:
248 |     """
249 |     :param installed: A map from archive RECORD path to installation RECORD
250 |         path.
251 |     """
252 |     installed_rows: List[InstalledCSVRow] = []
253 |     for row in old_csv_rows:
254 |         if len(row) > 3:
255 |             logger.warning("RECORD line has more than three elements: %s", row)
256 |         old_record_path = cast("RecordPath", row[0])
257 |         new_record_path = installed.pop(old_record_path, old_record_path)
258 |         if new_record_path in changed:
259 |             digest, length = rehash(_record_to_fs_path(new_record_path, lib_dir))
260 |         else:
261 |             digest = row[1] if len(row) > 1 else ""
262 |             length = row[2] if len(row) > 2 else ""
263 |         installed_rows.append((new_record_path, digest, length))
264 |     for f in generated:
265 |         path = _fs_to_record_path(f, lib_dir)
266 |         digest, length = rehash(f)
267 |         installed_rows.append((path, digest, length))
268 |     return installed_rows + [
269 |         (installed_record_path, "", "") for installed_record_path in installed.values()
270 |     ]
271 | 
272 | 
273 | def get_console_script_specs(console: Dict[str, str]) -> List[str]:
274 |     """
275 |     Given the mapping from entrypoint name to callable, return the relevant
276 |     console script specs.
277 |     """
278 |     # Don't mutate caller's version
279 |     console = console.copy()
280 | 
281 |     scripts_to_generate = []
282 | 
283 |     # Special case pip and setuptools to generate versioned wrappers
284 |     #
285 |     # The issue is that some projects (specifically, pip and setuptools) use
286 |     # code in setup.py to create "versioned" entry points - pip2.7 on Python
287 |     # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into
288 |     # the wheel metadata at build time, and so if the wheel is installed with
289 |     # a *different* version of Python the entry points will be wrong. The
290 |     # correct fix for this is to enhance the metadata to be able to describe
291 |     # such versioned entry points.
292 |     # Currently, projects using versioned entry points will either have
293 |     # incorrect versioned entry points, or they will not be able to distribute
294 |     # "universal" wheels (i.e., they will need a wheel per Python version).
295 |     #
296 |     # Because setuptools and pip are bundled with _ensurepip and virtualenv,
297 |     # we need to use universal wheels. As a workaround, we
298 |     # override the versioned entry points in the wheel and generate the
299 |     # correct ones.
300 |     #
301 |     # To add the level of hack in this section of code, in order to support
302 |     # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment
303 |     # variable which will control which version scripts get installed.
304 |     #
305 |     # ENSUREPIP_OPTIONS=altinstall
306 |     #   - Only pipX.Y and easy_install-X.Y will be generated and installed
307 |     # ENSUREPIP_OPTIONS=install
308 |     #   - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note
309 |     #     that this option is technically if ENSUREPIP_OPTIONS is set and is
310 |     #     not altinstall
311 |     # DEFAULT
312 |     #   - The default behavior is to install pip, pipX, pipX.Y, easy_install
313 |     #     and easy_install-X.Y.
314 |     pip_script = console.pop("pip", None)
315 |     if pip_script:
316 |         if "ENSUREPIP_OPTIONS" not in os.environ:
317 |             scripts_to_generate.append("pip = " + pip_script)
318 | 
319 |         if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall":
320 |             scripts_to_generate.append(f"pip{sys.version_info[0]} = {pip_script}")
321 | 
322 |         scripts_to_generate.append(f"pip{get_major_minor_version()} = {pip_script}")
323 |         # Delete any other versioned pip entry points
324 |         pip_ep = [k for k in console if re.match(r"pip(\d+(\.\d+)?)?$", k)]
325 |         for k in pip_ep:
326 |             del console[k]
327 |     easy_install_script = console.pop("easy_install", None)
328 |     if easy_install_script:
329 |         if "ENSUREPIP_OPTIONS" not in os.environ:
330 |             scripts_to_generate.append("easy_install = " + easy_install_script)
331 | 
332 |         scripts_to_generate.append(
333 |             f"easy_install-{get_major_minor_version()} = {easy_install_script}"
334 |         )
335 |         # Delete any other versioned easy_install entry points
336 |         easy_install_ep = [
337 |             k for k in console if re.match(r"easy_install(-\d+\.\d+)?$", k)
338 |         ]
339 |         for k in easy_install_ep:
340 |             del console[k]
341 | 
342 |     # Generate the console entry points specified in the wheel
343 |     scripts_to_generate.extend(starmap("{} = {}".format, console.items()))
344 | 
345 |     return scripts_to_generate
346 | 
347 | 
348 | class ZipBackedFile:
349 |     def __init__(
350 |         self, src_record_path: RecordPath, dest_path: str, zip_file: ZipFile
351 |     ) -> None:
352 |         self.src_record_path = src_record_path
353 |         self.dest_path = dest_path
354 |         self._zip_file = zip_file
355 |         self.changed = False
356 | 
357 |     def _getinfo(self) -> ZipInfo:
358 |         return self._zip_file.getinfo(self.src_record_path)
359 | 
360 |     def save(self) -> None:
361 |         # When we open the output file below, any existing file is truncated
362 |         # before we start writing the new contents. This is fine in most
363 |         # cases, but can cause a segfault if pip has loaded a shared
364 |         # object (e.g. from pyopenssl through its vendored urllib3)
365 |         # Since the shared object is mmap'd an attempt to call a
366 |         # symbol in it will then cause a segfault. Unlinking the file
367 |         # allows writing of new contents while allowing the process to
368 |         # continue to use the old copy.
369 |         if os.path.exists(self.dest_path):
370 |             os.unlink(self.dest_path)
371 | 
372 |         zipinfo = self._getinfo()
373 | 
374 |         # optimization: the file is created by open(),
375 |         # skip the decompression when there is 0 bytes to decompress.
376 |         with open(self.dest_path, "wb") as dest:
377 |             if zipinfo.file_size > 0:
378 |                 with self._zip_file.open(zipinfo) as f:
379 |                     blocksize = min(zipinfo.file_size, 1024 * 1024)
380 |                     shutil.copyfileobj(f, dest, blocksize)
381 | 
382 |         if zip_item_is_executable(zipinfo):
383 |             set_extracted_file_to_default_mode_plus_executable(self.dest_path)
384 | 
385 | 
386 | class ScriptFile:
387 |     def __init__(self, file: "File") -> None:
388 |         self._file = file
389 |         self.src_record_path = self._file.src_record_path
390 |         self.dest_path = self._file.dest_path
391 |         self.changed = False
392 | 
393 |     def save(self) -> None:
394 |         self._file.save()
395 |         self.changed = fix_script(self.dest_path)
396 | 
397 | 
398 | class MissingCallableSuffix(InstallationError):
399 |     def __init__(self, entry_point: str) -> None:
400 |         super().__init__(
401 |             f"Invalid script entry point: {entry_point} - A callable "
402 |             "suffix is required. Cf https://packaging.python.org/"
403 |             "specifications/entry-points/#use-for-scripts for more "
404 |             "information."
405 |         )
406 | 
407 | 
408 | def _raise_for_invalid_entrypoint(specification: str) -> None:
409 |     entry = get_export_entry(specification)
410 |     if entry is not None and entry.suffix is None:
411 |         raise MissingCallableSuffix(str(entry))
412 | 
413 | 
414 | class PipScriptMaker(ScriptMaker):
415 |     def make(
416 |         self, specification: str, options: Optional[Dict[str, Any]] = None
417 |     ) -> List[str]:
418 |         _raise_for_invalid_entrypoint(specification)
419 |         return super().make(specification, options)
420 | 
421 | 
422 | def _install_wheel(  # noqa: C901, PLR0915 function is too long
423 |     name: str,
424 |     wheel_zip: ZipFile,
425 |     wheel_path: str,
426 |     scheme: Scheme,
427 |     pycompile: bool = True,
428 |     warn_script_location: bool = True,
429 |     direct_url: Optional[DirectUrl] = None,
430 |     requested: bool = False,
431 | ) -> None:
432 |     """Install a wheel.
433 | 
434 |     :param name: Name of the project to install
435 |     :param wheel_zip: open ZipFile for wheel being installed
436 |     :param scheme: Distutils scheme dictating the install directories
437 |     :param req_description: String used in place of the requirement, for
438 |         logging
439 |     :param pycompile: Whether to byte-compile installed Python files
440 |     :param warn_script_location: Whether to check that scripts are installed
441 |         into a directory on PATH
442 |     :raises UnsupportedWheel:
443 |         * when the directory holds an unpacked wheel with incompatible
444 |           Wheel-Version
445 |         * when the .dist-info dir does not match the wheel
446 |     """
447 |     info_dir, metadata = parse_wheel(wheel_zip, name)
448 | 
449 |     if wheel_root_is_purelib(metadata):
450 |         lib_dir = scheme.purelib
451 |     else:
452 |         lib_dir = scheme.platlib
453 | 
454 |     # Record details of the files moved
455 |     #   installed = files copied from the wheel to the destination
456 |     #   changed = files changed while installing (scripts #! line typically)
457 |     #   generated = files newly generated during the install (script wrappers)
458 |     installed: Dict[RecordPath, RecordPath] = {}
459 |     changed: Set[RecordPath] = set()
460 |     generated: List[str] = []
461 | 
462 |     def record_installed(
463 |         srcfile: RecordPath, destfile: str, modified: bool = False
464 |     ) -> None:
465 |         """Map archive RECORD paths to installation RECORD paths."""
466 |         newpath = _fs_to_record_path(destfile, lib_dir)
467 |         installed[srcfile] = newpath
468 |         if modified:
469 |             changed.add(newpath)
470 | 
471 |     def is_dir_path(path: RecordPath) -> bool:
472 |         return path.endswith("/")
473 | 
474 |     def assert_no_path_traversal(dest_dir_path: str, target_path: str) -> None:
475 |         if not is_within_directory(dest_dir_path, target_path):
476 |             message = (
477 |                 "The wheel {!r} has a file {!r} trying to install"
478 |                 " outside the target directory {!r}"
479 |             )
480 |             raise InstallationError(
481 |                 message.format(wheel_path, target_path, dest_dir_path)
482 |             )
483 | 
484 |     def root_scheme_file_maker(
485 |         zip_file: ZipFile, dest: str
486 |     ) -> Callable[[RecordPath], "File"]:
487 |         def make_root_scheme_file(record_path: RecordPath) -> "File":
488 |             normed_path = os.path.normpath(record_path)
489 |             dest_path = os.path.join(dest, normed_path)
490 |             assert_no_path_traversal(dest, dest_path)
491 |             return ZipBackedFile(record_path, dest_path, zip_file)
492 | 
493 |         return make_root_scheme_file
494 | 
495 |     def data_scheme_file_maker(
496 |         zip_file: ZipFile, scheme: Scheme
497 |     ) -> Callable[[RecordPath], "File"]:
498 |         scheme_paths = {key: getattr(scheme, key) for key in SCHEME_KEYS}
499 | 
500 |         def make_data_scheme_file(record_path: RecordPath) -> "File":
501 |             normed_path = os.path.normpath(record_path)
502 |             try:
503 |                 _, scheme_key, dest_subpath = normed_path.split(os.path.sep, 2)
504 |             except ValueError:
505 |                 message = (
506 |                     f"Unexpected file in {wheel_path}: {record_path!r}. .data directory"
507 |                     " contents should be named like: '<scheme key>/<path>'."
508 |                 )
509 |                 raise InstallationError(message)
510 | 
511 |             try:
512 |                 scheme_path = scheme_paths[scheme_key]
513 |             except KeyError:
514 |                 valid_scheme_keys = ", ".join(sorted(scheme_paths))
515 |                 message = (
516 |                     f"Unknown scheme key used in {wheel_path}: {scheme_key} "
517 |                     f"(for file {record_path!r}). .data directory contents "
518 |                     f"should be in subdirectories named with a valid scheme "
519 |                     f"key ({valid_scheme_keys})"
520 |                 )
521 |                 raise InstallationError(message)
522 | 
523 |             dest_path = os.path.join(scheme_path, dest_subpath)
524 |             assert_no_path_traversal(scheme_path, dest_path)
525 |             return ZipBackedFile(record_path, dest_path, zip_file)
526 | 
527 |         return make_data_scheme_file
528 | 
529 |     def is_data_scheme_path(path: RecordPath) -> bool:
530 |         return path.split("/", 1)[0].endswith(".data")
531 | 
532 |     paths = cast(List[RecordPath], wheel_zip.namelist())
533 |     file_paths = filterfalse(is_dir_path, paths)
534 |     root_scheme_paths, data_scheme_paths = partition(is_data_scheme_path, file_paths)
535 | 
536 |     make_root_scheme_file = root_scheme_file_maker(wheel_zip, lib_dir)
537 |     files: Iterator[File] = map(make_root_scheme_file, root_scheme_paths)
538 | 
539 |     def is_script_scheme_path(path: RecordPath) -> bool:
540 |         parts = path.split("/", 2)
541 |         return len(parts) > 2 and parts[0].endswith(".data") and parts[1] == "scripts"
542 | 
543 |     other_scheme_paths, script_scheme_paths = partition(
544 |         is_script_scheme_path, data_scheme_paths
545 |     )
546 | 
547 |     make_data_scheme_file = data_scheme_file_maker(wheel_zip, scheme)
548 |     other_scheme_files = map(make_data_scheme_file, other_scheme_paths)
549 |     files = chain(files, other_scheme_files)
550 | 
551 |     # Get the defined entry points
552 |     distribution = get_wheel_distribution(
553 |         FilesystemWheel(wheel_path),
554 |         canonicalize_name(name),
555 |     )
556 |     console, gui = get_entrypoints(distribution)
557 | 
558 |     def is_entrypoint_wrapper(file: "File") -> bool:
559 |         # EP, EP.exe and EP-script.py are scripts generated for
560 |         # entry point EP by setuptools
561 |         path = file.dest_path
562 |         name = os.path.basename(path)
563 |         if name.lower().endswith(".exe"):
564 |             matchname = name[:-4]
565 |         elif name.lower().endswith("-script.py"):
566 |             matchname = name[:-10]
567 |         elif name.lower().endswith(".pya"):
568 |             matchname = name[:-4]
569 |         else:
570 |             matchname = name
571 |         # Ignore setuptools-generated scripts
572 |         return matchname in console or matchname in gui
573 | 
574 |     script_scheme_files: Iterator[File] = map(
575 |         make_data_scheme_file, script_scheme_paths
576 |     )
577 |     script_scheme_files = filterfalse(is_entrypoint_wrapper, script_scheme_files)
578 |     script_scheme_files = map(ScriptFile, script_scheme_files)
579 |     files = chain(files, script_scheme_files)
580 | 
581 |     existing_parents = set()
582 |     for file in files:
583 |         # directory creation is lazy and after file filtering
584 |         # to ensure we don't install empty dirs; empty dirs can't be
585 |         # uninstalled.
586 |         parent_dir = os.path.dirname(file.dest_path)
587 |         if parent_dir not in existing_parents:
588 |             ensure_dir(parent_dir)
589 |             existing_parents.add(parent_dir)
590 |         file.save()
591 |         record_installed(file.src_record_path, file.dest_path, file.changed)
592 | 
593 |     def pyc_source_file_paths() -> Generator[str, None, None]:
594 |         # We de-duplicate installation paths, since there can be overlap (e.g.
595 |         # file in .data maps to same location as file in wheel root).
596 |         # Sorting installation paths makes it easier to reproduce and debug
597 |         # issues related to permissions on existing files.
598 |         for installed_path in sorted(set(installed.values())):
599 |             full_installed_path = os.path.join(lib_dir, installed_path)
600 |             if not os.path.isfile(full_installed_path):
601 |                 continue
602 |             if not full_installed_path.endswith(".py"):
603 |                 continue
604 |             yield full_installed_path
605 | 
606 |     def pyc_output_path(path: str) -> str:
607 |         """Return the path the pyc file would have been written to."""
608 |         return importlib.util.cache_from_source(path)
609 | 
610 |     # Compile all of the pyc files for the installed files
611 |     if pycompile:
612 |         with contextlib.redirect_stdout(
613 |             StreamWrapper.from_stream(sys.stdout)
614 |         ) as stdout:
615 |             with warnings.catch_warnings():
616 |                 warnings.filterwarnings("ignore")
617 |                 for path in pyc_source_file_paths():
618 |                     success = compileall.compile_file(path, force=True, quiet=True)
619 |                     if success:
620 |                         pyc_path = pyc_output_path(path)
621 |                         assert os.path.exists(pyc_path)
622 |                         pyc_record_path = cast(
623 |                             "RecordPath", pyc_path.replace(os.path.sep, "/")
624 |                         )
625 |                         record_installed(pyc_record_path, pyc_path)
626 |         logger.debug(stdout.getvalue())
627 | 
628 |     maker = PipScriptMaker(None, scheme.scripts)
629 | 
630 |     # Ensure old scripts are overwritten.
631 |     # See https://github.com/pypa/pip/issues/1800
632 |     maker.clobber = True
633 | 
634 |     # Ensure we don't generate any variants for scripts because this is almost
635 |     # never what somebody wants.
636 |     # See https://bitbucket.org/pypa/distlib/issue/35/
637 |     maker.variants = {""}
638 | 
639 |     # This is required because otherwise distlib creates scripts that are not
640 |     # executable.
641 |     # See https://bitbucket.org/pypa/distlib/issue/32/
642 |     maker.set_mode = True
643 | 
644 |     # Generate the console and GUI entry points specified in the wheel
645 |     scripts_to_generate = get_console_script_specs(console)
646 | 
647 |     gui_scripts_to_generate = list(starmap("{} = {}".format, gui.items()))
648 | 
649 |     generated_console_scripts = maker.make_multiple(scripts_to_generate)
650 |     generated.extend(generated_console_scripts)
651 | 
652 |     generated.extend(maker.make_multiple(gui_scripts_to_generate, {"gui": True}))
653 | 
654 |     if warn_script_location:
655 |         msg = message_about_scripts_not_on_PATH(generated_console_scripts)
656 |         if msg is not None:
657 |             logger.warning(msg)
658 | 
659 |     generated_file_mode = 0o666 & ~current_umask()
660 | 
661 |     @contextlib.contextmanager
662 |     def _generate_file(path: str, **kwargs: Any) -> Generator[BinaryIO, None, None]:
663 |         with adjacent_tmp_file(path, **kwargs) as f:
664 |             yield f
665 |         os.chmod(f.name, generated_file_mode)
666 |         replace(f.name, path)
667 | 
668 |     dest_info_dir = os.path.join(lib_dir, info_dir)
669 | 
670 |     # Record pip as the installer
671 |     installer_path = os.path.join(dest_info_dir, "INSTALLER")
672 |     with _generate_file(installer_path) as installer_file:
673 |         installer_file.write(b"pip\n")
674 |     generated.append(installer_path)
675 | 
676 |     # Record the PEP 610 direct URL reference
677 |     if direct_url is not None:
678 |         direct_url_path = os.path.join(dest_info_dir, DIRECT_URL_METADATA_NAME)
679 |         with _generate_file(direct_url_path) as direct_url_file:
680 |             direct_url_file.write(direct_url.to_json().encode("utf-8"))
681 |         generated.append(direct_url_path)
682 | 
683 |     # Record the REQUESTED file
684 |     if requested:
685 |         requested_path = os.path.join(dest_info_dir, "REQUESTED")
686 |         with open(requested_path, "wb"):
687 |             pass
688 |         generated.append(requested_path)
689 | 
690 |     record_text = distribution.read_text("RECORD")
691 |     record_rows = list(csv.reader(record_text.splitlines()))
692 | 
693 |     rows = get_csv_rows_for_installed(
694 |         record_rows,
695 |         installed=installed,
696 |         changed=changed,
697 |         generated=generated,
698 |         lib_dir=lib_dir,
699 |     )
700 | 
701 |     # Record details of all files installed
702 |     record_path = os.path.join(dest_info_dir, "RECORD")
703 | 
704 |     with _generate_file(record_path, **csv_io_kwargs("w")) as record_file:
705 |         # Explicitly cast to typing.IO[str] as a workaround for the mypy error:
706 |         # "writer" has incompatible type "BinaryIO"; expected "_Writer"
707 |         writer = csv.writer(cast("IO[str]", record_file))
708 |         writer.writerows(_normalized_outrows(rows))
709 | 
710 | 
711 | @contextlib.contextmanager
712 | def req_error_context(req_description: str) -> Generator[None, None, None]:
713 |     try:
714 |         yield
715 |     except InstallationError as e:
716 |         message = f"For req: {req_description}. {e.args[0]}"
717 |         raise InstallationError(message) from e
718 | 
719 | 
720 | def install_wheel(
721 |     name: str,
722 |     wheel_path: str,
723 |     scheme: Scheme,
724 |     req_description: str,
725 |     pycompile: bool = True,
726 |     warn_script_location: bool = True,
727 |     direct_url: Optional[DirectUrl] = None,
728 |     requested: bool = False,
729 | ) -> None:
730 |     with ZipFile(wheel_path, allowZip64=True) as z:
731 |         with req_error_context(req_description):
732 |             _install_wheel(
733 |                 name=name,
734 |                 wheel_zip=z,
735 |                 wheel_path=wheel_path,
736 |                 scheme=scheme,
737 |                 pycompile=pycompile,
738 |                 warn_script_location=warn_script_location,
739 |                 direct_url=direct_url,
740 |                 requested=requested,
741 |             )
742 | 
```
Page 88/168FirstPrevNextLast