#
tokens: 47198/50000 2/808 files (page 79/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 79 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/_internal/utils/misc.py:
--------------------------------------------------------------------------------

```python
  1 | import errno
  2 | import getpass
  3 | import hashlib
  4 | import logging
  5 | import os
  6 | import posixpath
  7 | import shutil
  8 | import stat
  9 | import sys
 10 | import sysconfig
 11 | import urllib.parse
 12 | from dataclasses import dataclass
 13 | from functools import partial
 14 | from io import StringIO
 15 | from itertools import filterfalse, tee, zip_longest
 16 | from pathlib import Path
 17 | from types import FunctionType, TracebackType
 18 | from typing import (
 19 |     Any,
 20 |     BinaryIO,
 21 |     Callable,
 22 |     Dict,
 23 |     Generator,
 24 |     Iterable,
 25 |     Iterator,
 26 |     List,
 27 |     Optional,
 28 |     TextIO,
 29 |     Tuple,
 30 |     Type,
 31 |     TypeVar,
 32 |     Union,
 33 |     cast,
 34 | )
 35 | 
 36 | from pip._vendor.packaging.requirements import Requirement
 37 | from pip._vendor.pyproject_hooks import BuildBackendHookCaller
 38 | 
 39 | from pip import __version__
 40 | from pip._internal.exceptions import CommandError, ExternallyManagedEnvironment
 41 | from pip._internal.locations import get_major_minor_version
 42 | from pip._internal.utils.compat import WINDOWS
 43 | from pip._internal.utils.retry import retry
 44 | from pip._internal.utils.virtualenv import running_under_virtualenv
 45 | 
 46 | __all__ = [
 47 |     "rmtree",
 48 |     "display_path",
 49 |     "backup_dir",
 50 |     "ask",
 51 |     "splitext",
 52 |     "format_size",
 53 |     "is_installable_dir",
 54 |     "normalize_path",
 55 |     "renames",
 56 |     "get_prog",
 57 |     "ensure_dir",
 58 |     "remove_auth_from_url",
 59 |     "check_externally_managed",
 60 |     "ConfiguredBuildBackendHookCaller",
 61 | ]
 62 | 
 63 | logger = logging.getLogger(__name__)
 64 | 
 65 | T = TypeVar("T")
 66 | ExcInfo = Tuple[Type[BaseException], BaseException, TracebackType]
 67 | VersionInfo = Tuple[int, int, int]
 68 | NetlocTuple = Tuple[str, Tuple[Optional[str], Optional[str]]]
 69 | OnExc = Callable[[FunctionType, Path, BaseException], Any]
 70 | OnErr = Callable[[FunctionType, Path, ExcInfo], Any]
 71 | 
 72 | FILE_CHUNK_SIZE = 1024 * 1024
 73 | 
 74 | 
 75 | def get_pip_version() -> str:
 76 |     pip_pkg_dir = os.path.join(os.path.dirname(__file__), "..", "..")
 77 |     pip_pkg_dir = os.path.abspath(pip_pkg_dir)
 78 | 
 79 |     return f"pip {__version__} from {pip_pkg_dir} (python {get_major_minor_version()})"
 80 | 
 81 | 
 82 | def normalize_version_info(py_version_info: Tuple[int, ...]) -> Tuple[int, int, int]:
 83 |     """
 84 |     Convert a tuple of ints representing a Python version to one of length
 85 |     three.
 86 | 
 87 |     :param py_version_info: a tuple of ints representing a Python version,
 88 |         or None to specify no version. The tuple can have any length.
 89 | 
 90 |     :return: a tuple of length three if `py_version_info` is non-None.
 91 |         Otherwise, return `py_version_info` unchanged (i.e. None).
 92 |     """
 93 |     if len(py_version_info) < 3:
 94 |         py_version_info += (3 - len(py_version_info)) * (0,)
 95 |     elif len(py_version_info) > 3:
 96 |         py_version_info = py_version_info[:3]
 97 | 
 98 |     return cast("VersionInfo", py_version_info)
 99 | 
100 | 
101 | def ensure_dir(path: str) -> None:
102 |     """os.path.makedirs without EEXIST."""
103 |     try:
104 |         os.makedirs(path)
105 |     except OSError as e:
106 |         # Windows can raise spurious ENOTEMPTY errors. See #6426.
107 |         if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY:
108 |             raise
109 | 
110 | 
111 | def get_prog() -> str:
112 |     try:
113 |         prog = os.path.basename(sys.argv[0])
114 |         if prog in ("__main__.py", "-c"):
115 |             return f"{sys.executable} -m pip"
116 |         else:
117 |             return prog
118 |     except (AttributeError, TypeError, IndexError):
119 |         pass
120 |     return "pip"
121 | 
122 | 
123 | # Retry every half second for up to 3 seconds
124 | @retry(stop_after_delay=3, wait=0.5)
125 | def rmtree(
126 |     dir: str, ignore_errors: bool = False, onexc: Optional[OnExc] = None
127 | ) -> None:
128 |     if ignore_errors:
129 |         onexc = _onerror_ignore
130 |     if onexc is None:
131 |         onexc = _onerror_reraise
132 |     handler: OnErr = partial(
133 |         # `[func, path, Union[ExcInfo, BaseException]] -> Any` is equivalent to
134 |         # `Union[([func, path, ExcInfo] -> Any), ([func, path, BaseException] -> Any)]`.
135 |         cast(Union[OnExc, OnErr], rmtree_errorhandler),
136 |         onexc=onexc,
137 |     )
138 |     if sys.version_info >= (3, 12):
139 |         # See https://docs.python.org/3.12/whatsnew/3.12.html#shutil.
140 |         shutil.rmtree(dir, onexc=handler)  # type: ignore
141 |     else:
142 |         shutil.rmtree(dir, onerror=handler)  # type: ignore
143 | 
144 | 
145 | def _onerror_ignore(*_args: Any) -> None:
146 |     pass
147 | 
148 | 
149 | def _onerror_reraise(*_args: Any) -> None:
150 |     raise  # noqa: PLE0704 - Bare exception used to reraise existing exception
151 | 
152 | 
153 | def rmtree_errorhandler(
154 |     func: FunctionType,
155 |     path: Path,
156 |     exc_info: Union[ExcInfo, BaseException],
157 |     *,
158 |     onexc: OnExc = _onerror_reraise,
159 | ) -> None:
160 |     """
161 |     `rmtree` error handler to 'force' a file remove (i.e. like `rm -f`).
162 | 
163 |     * If a file is readonly then it's write flag is set and operation is
164 |       retried.
165 | 
166 |     * `onerror` is the original callback from `rmtree(... onerror=onerror)`
167 |       that is chained at the end if the "rm -f" still fails.
168 |     """
169 |     try:
170 |         st_mode = os.stat(path).st_mode
171 |     except OSError:
172 |         # it's equivalent to os.path.exists
173 |         return
174 | 
175 |     if not st_mode & stat.S_IWRITE:
176 |         # convert to read/write
177 |         try:
178 |             os.chmod(path, st_mode | stat.S_IWRITE)
179 |         except OSError:
180 |             pass
181 |         else:
182 |             # use the original function to repeat the operation
183 |             try:
184 |                 func(path)
185 |                 return
186 |             except OSError:
187 |                 pass
188 | 
189 |     if not isinstance(exc_info, BaseException):
190 |         _, exc_info, _ = exc_info
191 |     onexc(func, path, exc_info)
192 | 
193 | 
194 | def display_path(path: str) -> str:
195 |     """Gives the display value for a given path, making it relative to cwd
196 |     if possible."""
197 |     path = os.path.normcase(os.path.abspath(path))
198 |     if path.startswith(os.getcwd() + os.path.sep):
199 |         path = "." + path[len(os.getcwd()) :]
200 |     return path
201 | 
202 | 
203 | def backup_dir(dir: str, ext: str = ".bak") -> str:
204 |     """Figure out the name of a directory to back up the given dir to
205 |     (adding .bak, .bak2, etc)"""
206 |     n = 1
207 |     extension = ext
208 |     while os.path.exists(dir + extension):
209 |         n += 1
210 |         extension = ext + str(n)
211 |     return dir + extension
212 | 
213 | 
214 | def ask_path_exists(message: str, options: Iterable[str]) -> str:
215 |     for action in os.environ.get("PIP_EXISTS_ACTION", "").split():
216 |         if action in options:
217 |             return action
218 |     return ask(message, options)
219 | 
220 | 
221 | def _check_no_input(message: str) -> None:
222 |     """Raise an error if no input is allowed."""
223 |     if os.environ.get("PIP_NO_INPUT"):
224 |         raise Exception(
225 |             f"No input was expected ($PIP_NO_INPUT set); question: {message}"
226 |         )
227 | 
228 | 
229 | def ask(message: str, options: Iterable[str]) -> str:
230 |     """Ask the message interactively, with the given possible responses"""
231 |     while 1:
232 |         _check_no_input(message)
233 |         response = input(message)
234 |         response = response.strip().lower()
235 |         if response not in options:
236 |             print(
237 |                 "Your response ({!r}) was not one of the expected responses: "
238 |                 "{}".format(response, ", ".join(options))
239 |             )
240 |         else:
241 |             return response
242 | 
243 | 
244 | def ask_input(message: str) -> str:
245 |     """Ask for input interactively."""
246 |     _check_no_input(message)
247 |     return input(message)
248 | 
249 | 
250 | def ask_password(message: str) -> str:
251 |     """Ask for a password interactively."""
252 |     _check_no_input(message)
253 |     return getpass.getpass(message)
254 | 
255 | 
256 | def strtobool(val: str) -> int:
257 |     """Convert a string representation of truth to true (1) or false (0).
258 | 
259 |     True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
260 |     are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
261 |     'val' is anything else.
262 |     """
263 |     val = val.lower()
264 |     if val in ("y", "yes", "t", "true", "on", "1"):
265 |         return 1
266 |     elif val in ("n", "no", "f", "false", "off", "0"):
267 |         return 0
268 |     else:
269 |         raise ValueError(f"invalid truth value {val!r}")
270 | 
271 | 
272 | def format_size(bytes: float) -> str:
273 |     if bytes > 1000 * 1000:
274 |         return f"{bytes / 1000.0 / 1000:.1f} MB"
275 |     elif bytes > 10 * 1000:
276 |         return f"{int(bytes / 1000)} kB"
277 |     elif bytes > 1000:
278 |         return f"{bytes / 1000.0:.1f} kB"
279 |     else:
280 |         return f"{int(bytes)} bytes"
281 | 
282 | 
283 | def tabulate(rows: Iterable[Iterable[Any]]) -> Tuple[List[str], List[int]]:
284 |     """Return a list of formatted rows and a list of column sizes.
285 | 
286 |     For example::
287 | 
288 |     >>> tabulate([['foobar', 2000], [0xdeadbeef]])
289 |     (['foobar     2000', '3735928559'], [10, 4])
290 |     """
291 |     rows = [tuple(map(str, row)) for row in rows]
292 |     sizes = [max(map(len, col)) for col in zip_longest(*rows, fillvalue="")]
293 |     table = [" ".join(map(str.ljust, row, sizes)).rstrip() for row in rows]
294 |     return table, sizes
295 | 
296 | 
297 | def is_installable_dir(path: str) -> bool:
298 |     """Is path is a directory containing pyproject.toml or setup.py?
299 | 
300 |     If pyproject.toml exists, this is a PEP 517 project. Otherwise we look for
301 |     a legacy setuptools layout by identifying setup.py. We don't check for the
302 |     setup.cfg because using it without setup.py is only available for PEP 517
303 |     projects, which are already covered by the pyproject.toml check.
304 |     """
305 |     if not os.path.isdir(path):
306 |         return False
307 |     if os.path.isfile(os.path.join(path, "pyproject.toml")):
308 |         return True
309 |     if os.path.isfile(os.path.join(path, "setup.py")):
310 |         return True
311 |     return False
312 | 
313 | 
314 | def read_chunks(
315 |     file: BinaryIO, size: int = FILE_CHUNK_SIZE
316 | ) -> Generator[bytes, None, None]:
317 |     """Yield pieces of data from a file-like object until EOF."""
318 |     while True:
319 |         chunk = file.read(size)
320 |         if not chunk:
321 |             break
322 |         yield chunk
323 | 
324 | 
325 | def normalize_path(path: str, resolve_symlinks: bool = True) -> str:
326 |     """
327 |     Convert a path to its canonical, case-normalized, absolute version.
328 | 
329 |     """
330 |     path = os.path.expanduser(path)
331 |     if resolve_symlinks:
332 |         path = os.path.realpath(path)
333 |     else:
334 |         path = os.path.abspath(path)
335 |     return os.path.normcase(path)
336 | 
337 | 
338 | def splitext(path: str) -> Tuple[str, str]:
339 |     """Like os.path.splitext, but take off .tar too"""
340 |     base, ext = posixpath.splitext(path)
341 |     if base.lower().endswith(".tar"):
342 |         ext = base[-4:] + ext
343 |         base = base[:-4]
344 |     return base, ext
345 | 
346 | 
347 | def renames(old: str, new: str) -> None:
348 |     """Like os.renames(), but handles renaming across devices."""
349 |     # Implementation borrowed from os.renames().
350 |     head, tail = os.path.split(new)
351 |     if head and tail and not os.path.exists(head):
352 |         os.makedirs(head)
353 | 
354 |     shutil.move(old, new)
355 | 
356 |     head, tail = os.path.split(old)
357 |     if head and tail:
358 |         try:
359 |             os.removedirs(head)
360 |         except OSError:
361 |             pass
362 | 
363 | 
364 | def is_local(path: str) -> bool:
365 |     """
366 |     Return True if path is within sys.prefix, if we're running in a virtualenv.
367 | 
368 |     If we're not in a virtualenv, all paths are considered "local."
369 | 
370 |     Caution: this function assumes the head of path has been normalized
371 |     with normalize_path.
372 |     """
373 |     if not running_under_virtualenv():
374 |         return True
375 |     return path.startswith(normalize_path(sys.prefix))
376 | 
377 | 
378 | def write_output(msg: Any, *args: Any) -> None:
379 |     logger.info(msg, *args)
380 | 
381 | 
382 | class StreamWrapper(StringIO):
383 |     orig_stream: TextIO
384 | 
385 |     @classmethod
386 |     def from_stream(cls, orig_stream: TextIO) -> "StreamWrapper":
387 |         ret = cls()
388 |         ret.orig_stream = orig_stream
389 |         return ret
390 | 
391 |     # compileall.compile_dir() needs stdout.encoding to print to stdout
392 |     # type ignore is because TextIOBase.encoding is writeable
393 |     @property
394 |     def encoding(self) -> str:  # type: ignore
395 |         return self.orig_stream.encoding
396 | 
397 | 
398 | # Simulates an enum
399 | def enum(*sequential: Any, **named: Any) -> Type[Any]:
400 |     enums = dict(zip(sequential, range(len(sequential))), **named)
401 |     reverse = {value: key for key, value in enums.items()}
402 |     enums["reverse_mapping"] = reverse
403 |     return type("Enum", (), enums)
404 | 
405 | 
406 | def build_netloc(host: str, port: Optional[int]) -> str:
407 |     """
408 |     Build a netloc from a host-port pair
409 |     """
410 |     if port is None:
411 |         return host
412 |     if ":" in host:
413 |         # Only wrap host with square brackets when it is IPv6
414 |         host = f"[{host}]"
415 |     return f"{host}:{port}"
416 | 
417 | 
418 | def build_url_from_netloc(netloc: str, scheme: str = "https") -> str:
419 |     """
420 |     Build a full URL from a netloc.
421 |     """
422 |     if netloc.count(":") >= 2 and "@" not in netloc and "[" not in netloc:
423 |         # It must be a bare IPv6 address, so wrap it with brackets.
424 |         netloc = f"[{netloc}]"
425 |     return f"{scheme}://{netloc}"
426 | 
427 | 
428 | def parse_netloc(netloc: str) -> Tuple[Optional[str], Optional[int]]:
429 |     """
430 |     Return the host-port pair from a netloc.
431 |     """
432 |     url = build_url_from_netloc(netloc)
433 |     parsed = urllib.parse.urlparse(url)
434 |     return parsed.hostname, parsed.port
435 | 
436 | 
437 | def split_auth_from_netloc(netloc: str) -> NetlocTuple:
438 |     """
439 |     Parse out and remove the auth information from a netloc.
440 | 
441 |     Returns: (netloc, (username, password)).
442 |     """
443 |     if "@" not in netloc:
444 |         return netloc, (None, None)
445 | 
446 |     # Split from the right because that's how urllib.parse.urlsplit()
447 |     # behaves if more than one @ is present (which can be checked using
448 |     # the password attribute of urlsplit()'s return value).
449 |     auth, netloc = netloc.rsplit("@", 1)
450 |     pw: Optional[str] = None
451 |     if ":" in auth:
452 |         # Split from the left because that's how urllib.parse.urlsplit()
453 |         # behaves if more than one : is present (which again can be checked
454 |         # using the password attribute of the return value)
455 |         user, pw = auth.split(":", 1)
456 |     else:
457 |         user, pw = auth, None
458 | 
459 |     user = urllib.parse.unquote(user)
460 |     if pw is not None:
461 |         pw = urllib.parse.unquote(pw)
462 | 
463 |     return netloc, (user, pw)
464 | 
465 | 
466 | def redact_netloc(netloc: str) -> str:
467 |     """
468 |     Replace the sensitive data in a netloc with "****", if it exists.
469 | 
470 |     For example:
471 |         - "user:[email protected]" returns "user:****@example.com"
472 |         - "[email protected]" returns "****@example.com"
473 |     """
474 |     netloc, (user, password) = split_auth_from_netloc(netloc)
475 |     if user is None:
476 |         return netloc
477 |     if password is None:
478 |         user = "****"
479 |         password = ""
480 |     else:
481 |         user = urllib.parse.quote(user)
482 |         password = ":****"
483 |     return f"{user}{password}@{netloc}"
484 | 
485 | 
486 | def _transform_url(
487 |     url: str, transform_netloc: Callable[[str], Tuple[Any, ...]]
488 | ) -> Tuple[str, NetlocTuple]:
489 |     """Transform and replace netloc in a url.
490 | 
491 |     transform_netloc is a function taking the netloc and returning a
492 |     tuple. The first element of this tuple is the new netloc. The
493 |     entire tuple is returned.
494 | 
495 |     Returns a tuple containing the transformed url as item 0 and the
496 |     original tuple returned by transform_netloc as item 1.
497 |     """
498 |     purl = urllib.parse.urlsplit(url)
499 |     netloc_tuple = transform_netloc(purl.netloc)
500 |     # stripped url
501 |     url_pieces = (purl.scheme, netloc_tuple[0], purl.path, purl.query, purl.fragment)
502 |     surl = urllib.parse.urlunsplit(url_pieces)
503 |     return surl, cast("NetlocTuple", netloc_tuple)
504 | 
505 | 
506 | def _get_netloc(netloc: str) -> NetlocTuple:
507 |     return split_auth_from_netloc(netloc)
508 | 
509 | 
510 | def _redact_netloc(netloc: str) -> Tuple[str]:
511 |     return (redact_netloc(netloc),)
512 | 
513 | 
514 | def split_auth_netloc_from_url(
515 |     url: str,
516 | ) -> Tuple[str, str, Tuple[Optional[str], Optional[str]]]:
517 |     """
518 |     Parse a url into separate netloc, auth, and url with no auth.
519 | 
520 |     Returns: (url_without_auth, netloc, (username, password))
521 |     """
522 |     url_without_auth, (netloc, auth) = _transform_url(url, _get_netloc)
523 |     return url_without_auth, netloc, auth
524 | 
525 | 
526 | def remove_auth_from_url(url: str) -> str:
527 |     """Return a copy of url with 'username:password@' removed."""
528 |     # username/pass params are passed to subversion through flags
529 |     # and are not recognized in the url.
530 |     return _transform_url(url, _get_netloc)[0]
531 | 
532 | 
533 | def redact_auth_from_url(url: str) -> str:
534 |     """Replace the password in a given url with ****."""
535 |     return _transform_url(url, _redact_netloc)[0]
536 | 
537 | 
538 | def redact_auth_from_requirement(req: Requirement) -> str:
539 |     """Replace the password in a given requirement url with ****."""
540 |     if not req.url:
541 |         return str(req)
542 |     return str(req).replace(req.url, redact_auth_from_url(req.url))
543 | 
544 | 
545 | @dataclass(frozen=True)
546 | class HiddenText:
547 |     secret: str
548 |     redacted: str
549 | 
550 |     def __repr__(self) -> str:
551 |         return f"<HiddenText {str(self)!r}>"
552 | 
553 |     def __str__(self) -> str:
554 |         return self.redacted
555 | 
556 |     # This is useful for testing.
557 |     def __eq__(self, other: Any) -> bool:
558 |         if type(self) != type(other):
559 |             return False
560 | 
561 |         # The string being used for redaction doesn't also have to match,
562 |         # just the raw, original string.
563 |         return self.secret == other.secret
564 | 
565 | 
566 | def hide_value(value: str) -> HiddenText:
567 |     return HiddenText(value, redacted="****")
568 | 
569 | 
570 | def hide_url(url: str) -> HiddenText:
571 |     redacted = redact_auth_from_url(url)
572 |     return HiddenText(url, redacted=redacted)
573 | 
574 | 
575 | def protect_pip_from_modification_on_windows(modifying_pip: bool) -> None:
576 |     """Protection of pip.exe from modification on Windows
577 | 
578 |     On Windows, any operation modifying pip should be run as:
579 |         python -m pip ...
580 |     """
581 |     pip_names = [
582 |         "pip",
583 |         f"pip{sys.version_info.major}",
584 |         f"pip{sys.version_info.major}.{sys.version_info.minor}",
585 |     ]
586 | 
587 |     # See https://github.com/pypa/pip/issues/1299 for more discussion
588 |     should_show_use_python_msg = (
589 |         modifying_pip and WINDOWS and os.path.basename(sys.argv[0]) in pip_names
590 |     )
591 | 
592 |     if should_show_use_python_msg:
593 |         new_command = [sys.executable, "-m", "pip"] + sys.argv[1:]
594 |         raise CommandError(
595 |             "To modify pip, please run the following command:\n{}".format(
596 |                 " ".join(new_command)
597 |             )
598 |         )
599 | 
600 | 
601 | def check_externally_managed() -> None:
602 |     """Check whether the current environment is externally managed.
603 | 
604 |     If the ``EXTERNALLY-MANAGED`` config file is found, the current environment
605 |     is considered externally managed, and an ExternallyManagedEnvironment is
606 |     raised.
607 |     """
608 |     if running_under_virtualenv():
609 |         return
610 |     marker = os.path.join(sysconfig.get_path("stdlib"), "EXTERNALLY-MANAGED")
611 |     if not os.path.isfile(marker):
612 |         return
613 |     raise ExternallyManagedEnvironment.from_config(marker)
614 | 
615 | 
616 | def is_console_interactive() -> bool:
617 |     """Is this console interactive?"""
618 |     return sys.stdin is not None and sys.stdin.isatty()
619 | 
620 | 
621 | def hash_file(path: str, blocksize: int = 1 << 20) -> Tuple[Any, int]:
622 |     """Return (hash, length) for path using hashlib.sha256()"""
623 | 
624 |     h = hashlib.sha256()
625 |     length = 0
626 |     with open(path, "rb") as f:
627 |         for block in read_chunks(f, size=blocksize):
628 |             length += len(block)
629 |             h.update(block)
630 |     return h, length
631 | 
632 | 
633 | def pairwise(iterable: Iterable[Any]) -> Iterator[Tuple[Any, Any]]:
634 |     """
635 |     Return paired elements.
636 | 
637 |     For example:
638 |         s -> (s0, s1), (s2, s3), (s4, s5), ...
639 |     """
640 |     iterable = iter(iterable)
641 |     return zip_longest(iterable, iterable)
642 | 
643 | 
644 | def partition(
645 |     pred: Callable[[T], bool], iterable: Iterable[T]
646 | ) -> Tuple[Iterable[T], Iterable[T]]:
647 |     """
648 |     Use a predicate to partition entries into false entries and true entries,
649 |     like
650 | 
651 |         partition(is_odd, range(10)) --> 0 2 4 6 8   and  1 3 5 7 9
652 |     """
653 |     t1, t2 = tee(iterable)
654 |     return filterfalse(pred, t1), filter(pred, t2)
655 | 
656 | 
657 | class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller):
658 |     def __init__(
659 |         self,
660 |         config_holder: Any,
661 |         source_dir: str,
662 |         build_backend: str,
663 |         backend_path: Optional[str] = None,
664 |         runner: Optional[Callable[..., None]] = None,
665 |         python_executable: Optional[str] = None,
666 |     ):
667 |         super().__init__(
668 |             source_dir, build_backend, backend_path, runner, python_executable
669 |         )
670 |         self.config_holder = config_holder
671 | 
672 |     def build_wheel(
673 |         self,
674 |         wheel_directory: str,
675 |         config_settings: Optional[Dict[str, Union[str, List[str]]]] = None,
676 |         metadata_directory: Optional[str] = None,
677 |     ) -> str:
678 |         cs = self.config_holder.config_settings
679 |         return super().build_wheel(
680 |             wheel_directory, config_settings=cs, metadata_directory=metadata_directory
681 |         )
682 | 
683 |     def build_sdist(
684 |         self,
685 |         sdist_directory: str,
686 |         config_settings: Optional[Dict[str, Union[str, List[str]]]] = None,
687 |     ) -> str:
688 |         cs = self.config_holder.config_settings
689 |         return super().build_sdist(sdist_directory, config_settings=cs)
690 | 
691 |     def build_editable(
692 |         self,
693 |         wheel_directory: str,
694 |         config_settings: Optional[Dict[str, Union[str, List[str]]]] = None,
695 |         metadata_directory: Optional[str] = None,
696 |     ) -> str:
697 |         cs = self.config_holder.config_settings
698 |         return super().build_editable(
699 |             wheel_directory, config_settings=cs, metadata_directory=metadata_directory
700 |         )
701 | 
702 |     def get_requires_for_build_wheel(
703 |         self, config_settings: Optional[Dict[str, Union[str, List[str]]]] = None
704 |     ) -> List[str]:
705 |         cs = self.config_holder.config_settings
706 |         return super().get_requires_for_build_wheel(config_settings=cs)
707 | 
708 |     def get_requires_for_build_sdist(
709 |         self, config_settings: Optional[Dict[str, Union[str, List[str]]]] = None
710 |     ) -> List[str]:
711 |         cs = self.config_holder.config_settings
712 |         return super().get_requires_for_build_sdist(config_settings=cs)
713 | 
714 |     def get_requires_for_build_editable(
715 |         self, config_settings: Optional[Dict[str, Union[str, List[str]]]] = None
716 |     ) -> List[str]:
717 |         cs = self.config_holder.config_settings
718 |         return super().get_requires_for_build_editable(config_settings=cs)
719 | 
720 |     def prepare_metadata_for_build_wheel(
721 |         self,
722 |         metadata_directory: str,
723 |         config_settings: Optional[Dict[str, Union[str, List[str]]]] = None,
724 |         _allow_fallback: bool = True,
725 |     ) -> str:
726 |         cs = self.config_holder.config_settings
727 |         return super().prepare_metadata_for_build_wheel(
728 |             metadata_directory=metadata_directory,
729 |             config_settings=cs,
730 |             _allow_fallback=_allow_fallback,
731 |         )
732 | 
733 |     def prepare_metadata_for_build_editable(
734 |         self,
735 |         metadata_directory: str,
736 |         config_settings: Optional[Dict[str, Union[str, List[str]]]] = None,
737 |         _allow_fallback: bool = True,
738 |     ) -> str:
739 |         cs = self.config_holder.config_settings
740 |         return super().prepare_metadata_for_build_editable(
741 |             metadata_directory=metadata_directory,
742 |             config_settings=cs,
743 |             _allow_fallback=_allow_fallback,
744 |         )
745 | 
746 | 
747 | def warn_if_run_as_root() -> None:
748 |     """Output a warning for sudo users on Unix.
749 | 
750 |     In a virtual environment, sudo pip still writes to virtualenv.
751 |     On Windows, users may run pip as Administrator without issues.
752 |     This warning only applies to Unix root users outside of virtualenv.
753 |     """
754 |     if running_under_virtualenv():
755 |         return
756 |     if not hasattr(os, "getuid"):
757 |         return
758 |     # On Windows, there are no "system managed" Python packages. Installing as
759 |     # Administrator via pip is the correct way of updating system environments.
760 |     #
761 |     # We choose sys.platform over utils.compat.WINDOWS here to enable Mypy platform
762 |     # checks: https://mypy.readthedocs.io/en/stable/common_issues.html
763 |     if sys.platform == "win32" or sys.platform == "cygwin":
764 |         return
765 | 
766 |     if os.getuid() != 0:
767 |         return
768 | 
769 |     logger.warning(
770 |         "Running pip as the 'root' user can result in broken permissions and "
771 |         "conflicting behaviour with the system package manager, possibly "
772 |         "rendering your system unusable."
773 |         "It is recommended to use a virtual environment instead: "
774 |         "https://pip.pypa.io/warnings/venv. "
775 |         "Use the --root-user-action option if you know what you are doing and "
776 |         "want to suppress this warning."
777 |     )
778 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/distlib/version.py:
--------------------------------------------------------------------------------

```python
  1 | # -*- coding: utf-8 -*-
  2 | #
  3 | # Copyright (C) 2012-2023 The Python Software Foundation.
  4 | # See LICENSE.txt and CONTRIBUTORS.txt.
  5 | #
  6 | """
  7 | Implementation of a flexible versioning scheme providing support for PEP-440,
  8 | setuptools-compatible and semantic versioning.
  9 | """
 10 | 
 11 | import logging
 12 | import re
 13 | 
 14 | from .compat import string_types
 15 | from .util import parse_requirement
 16 | 
 17 | __all__ = ['NormalizedVersion', 'NormalizedMatcher',
 18 |            'LegacyVersion', 'LegacyMatcher',
 19 |            'SemanticVersion', 'SemanticMatcher',
 20 |            'UnsupportedVersionError', 'get_scheme']
 21 | 
 22 | logger = logging.getLogger(__name__)
 23 | 
 24 | 
 25 | class UnsupportedVersionError(ValueError):
 26 |     """This is an unsupported version."""
 27 |     pass
 28 | 
 29 | 
 30 | class Version(object):
 31 |     def __init__(self, s):
 32 |         self._string = s = s.strip()
 33 |         self._parts = parts = self.parse(s)
 34 |         assert isinstance(parts, tuple)
 35 |         assert len(parts) > 0
 36 | 
 37 |     def parse(self, s):
 38 |         raise NotImplementedError('please implement in a subclass')
 39 | 
 40 |     def _check_compatible(self, other):
 41 |         if type(self) != type(other):
 42 |             raise TypeError('cannot compare %r and %r' % (self, other))
 43 | 
 44 |     def __eq__(self, other):
 45 |         self._check_compatible(other)
 46 |         return self._parts == other._parts
 47 | 
 48 |     def __ne__(self, other):
 49 |         return not self.__eq__(other)
 50 | 
 51 |     def __lt__(self, other):
 52 |         self._check_compatible(other)
 53 |         return self._parts < other._parts
 54 | 
 55 |     def __gt__(self, other):
 56 |         return not (self.__lt__(other) or self.__eq__(other))
 57 | 
 58 |     def __le__(self, other):
 59 |         return self.__lt__(other) or self.__eq__(other)
 60 | 
 61 |     def __ge__(self, other):
 62 |         return self.__gt__(other) or self.__eq__(other)
 63 | 
 64 |     # See http://docs.python.org/reference/datamodel#object.__hash__
 65 |     def __hash__(self):
 66 |         return hash(self._parts)
 67 | 
 68 |     def __repr__(self):
 69 |         return "%s('%s')" % (self.__class__.__name__, self._string)
 70 | 
 71 |     def __str__(self):
 72 |         return self._string
 73 | 
 74 |     @property
 75 |     def is_prerelease(self):
 76 |         raise NotImplementedError('Please implement in subclasses.')
 77 | 
 78 | 
 79 | class Matcher(object):
 80 |     version_class = None
 81 | 
 82 |     # value is either a callable or the name of a method
 83 |     _operators = {
 84 |         '<': lambda v, c, p: v < c,
 85 |         '>': lambda v, c, p: v > c,
 86 |         '<=': lambda v, c, p: v == c or v < c,
 87 |         '>=': lambda v, c, p: v == c or v > c,
 88 |         '==': lambda v, c, p: v == c,
 89 |         '===': lambda v, c, p: v == c,
 90 |         # by default, compatible => >=.
 91 |         '~=': lambda v, c, p: v == c or v > c,
 92 |         '!=': lambda v, c, p: v != c,
 93 |     }
 94 | 
 95 |     # this is a method only to support alternative implementations
 96 |     # via overriding
 97 |     def parse_requirement(self, s):
 98 |         return parse_requirement(s)
 99 | 
100 |     def __init__(self, s):
101 |         if self.version_class is None:
102 |             raise ValueError('Please specify a version class')
103 |         self._string = s = s.strip()
104 |         r = self.parse_requirement(s)
105 |         if not r:
106 |             raise ValueError('Not valid: %r' % s)
107 |         self.name = r.name
108 |         self.key = self.name.lower()    # for case-insensitive comparisons
109 |         clist = []
110 |         if r.constraints:
111 |             # import pdb; pdb.set_trace()
112 |             for op, s in r.constraints:
113 |                 if s.endswith('.*'):
114 |                     if op not in ('==', '!='):
115 |                         raise ValueError('\'.*\' not allowed for '
116 |                                          '%r constraints' % op)
117 |                     # Could be a partial version (e.g. for '2.*') which
118 |                     # won't parse as a version, so keep it as a string
119 |                     vn, prefix = s[:-2], True
120 |                     # Just to check that vn is a valid version
121 |                     self.version_class(vn)
122 |                 else:
123 |                     # Should parse as a version, so we can create an
124 |                     # instance for the comparison
125 |                     vn, prefix = self.version_class(s), False
126 |                 clist.append((op, vn, prefix))
127 |         self._parts = tuple(clist)
128 | 
129 |     def match(self, version):
130 |         """
131 |         Check if the provided version matches the constraints.
132 | 
133 |         :param version: The version to match against this instance.
134 |         :type version: String or :class:`Version` instance.
135 |         """
136 |         if isinstance(version, string_types):
137 |             version = self.version_class(version)
138 |         for operator, constraint, prefix in self._parts:
139 |             f = self._operators.get(operator)
140 |             if isinstance(f, string_types):
141 |                 f = getattr(self, f)
142 |             if not f:
143 |                 msg = ('%r not implemented '
144 |                        'for %s' % (operator, self.__class__.__name__))
145 |                 raise NotImplementedError(msg)
146 |             if not f(version, constraint, prefix):
147 |                 return False
148 |         return True
149 | 
150 |     @property
151 |     def exact_version(self):
152 |         result = None
153 |         if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='):
154 |             result = self._parts[0][1]
155 |         return result
156 | 
157 |     def _check_compatible(self, other):
158 |         if type(self) != type(other) or self.name != other.name:
159 |             raise TypeError('cannot compare %s and %s' % (self, other))
160 | 
161 |     def __eq__(self, other):
162 |         self._check_compatible(other)
163 |         return self.key == other.key and self._parts == other._parts
164 | 
165 |     def __ne__(self, other):
166 |         return not self.__eq__(other)
167 | 
168 |     # See http://docs.python.org/reference/datamodel#object.__hash__
169 |     def __hash__(self):
170 |         return hash(self.key) + hash(self._parts)
171 | 
172 |     def __repr__(self):
173 |         return "%s(%r)" % (self.__class__.__name__, self._string)
174 | 
175 |     def __str__(self):
176 |         return self._string
177 | 
178 | 
179 | PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|alpha|b|beta|c|rc|pre|preview)(\d+)?)?'
180 |                                r'(\.(post|r|rev)(\d+)?)?([._-]?(dev)(\d+)?)?'
181 |                                r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$', re.I)
182 | 
183 | 
184 | def _pep_440_key(s):
185 |     s = s.strip()
186 |     m = PEP440_VERSION_RE.match(s)
187 |     if not m:
188 |         raise UnsupportedVersionError('Not a valid version: %s' % s)
189 |     groups = m.groups()
190 |     nums = tuple(int(v) for v in groups[1].split('.'))
191 |     while len(nums) > 1 and nums[-1] == 0:
192 |         nums = nums[:-1]
193 | 
194 |     if not groups[0]:
195 |         epoch = 0
196 |     else:
197 |         epoch = int(groups[0][:-1])
198 |     pre = groups[4:6]
199 |     post = groups[7:9]
200 |     dev = groups[10:12]
201 |     local = groups[13]
202 |     if pre == (None, None):
203 |         pre = ()
204 |     else:
205 |         if pre[1] is None:
206 |             pre = pre[0], 0
207 |         else:
208 |             pre = pre[0], int(pre[1])
209 |     if post == (None, None):
210 |         post = ()
211 |     else:
212 |         if post[1] is None:
213 |             post = post[0], 0
214 |         else:
215 |             post = post[0], int(post[1])
216 |     if dev == (None, None):
217 |         dev = ()
218 |     else:
219 |         if dev[1] is None:
220 |             dev = dev[0], 0
221 |         else:
222 |             dev = dev[0], int(dev[1])
223 |     if local is None:
224 |         local = ()
225 |     else:
226 |         parts = []
227 |         for part in local.split('.'):
228 |             # to ensure that numeric compares as > lexicographic, avoid
229 |             # comparing them directly, but encode a tuple which ensures
230 |             # correct sorting
231 |             if part.isdigit():
232 |                 part = (1, int(part))
233 |             else:
234 |                 part = (0, part)
235 |             parts.append(part)
236 |         local = tuple(parts)
237 |     if not pre:
238 |         # either before pre-release, or final release and after
239 |         if not post and dev:
240 |             # before pre-release
241 |             pre = ('a', -1)     # to sort before a0
242 |         else:
243 |             pre = ('z',)        # to sort after all pre-releases
244 |     # now look at the state of post and dev.
245 |     if not post:
246 |         post = ('_',)   # sort before 'a'
247 |     if not dev:
248 |         dev = ('final',)
249 | 
250 |     return epoch, nums, pre, post, dev, local
251 | 
252 | 
253 | _normalized_key = _pep_440_key
254 | 
255 | 
256 | class NormalizedVersion(Version):
257 |     """A rational version.
258 | 
259 |     Good:
260 |         1.2         # equivalent to "1.2.0"
261 |         1.2.0
262 |         1.2a1
263 |         1.2.3a2
264 |         1.2.3b1
265 |         1.2.3c1
266 |         1.2.3.4
267 |         TODO: fill this out
268 | 
269 |     Bad:
270 |         1           # minimum two numbers
271 |         1.2a        # release level must have a release serial
272 |         1.2.3b
273 |     """
274 |     def parse(self, s):
275 |         result = _normalized_key(s)
276 |         # _normalized_key loses trailing zeroes in the release
277 |         # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0
278 |         # However, PEP 440 prefix matching needs it: for example,
279 |         # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0).
280 |         m = PEP440_VERSION_RE.match(s)      # must succeed
281 |         groups = m.groups()
282 |         self._release_clause = tuple(int(v) for v in groups[1].split('.'))
283 |         return result
284 | 
285 |     PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev'])
286 | 
287 |     @property
288 |     def is_prerelease(self):
289 |         return any(t[0] in self.PREREL_TAGS for t in self._parts if t)
290 | 
291 | 
292 | def _match_prefix(x, y):
293 |     x = str(x)
294 |     y = str(y)
295 |     if x == y:
296 |         return True
297 |     if not x.startswith(y):
298 |         return False
299 |     n = len(y)
300 |     return x[n] == '.'
301 | 
302 | 
303 | class NormalizedMatcher(Matcher):
304 |     version_class = NormalizedVersion
305 | 
306 |     # value is either a callable or the name of a method
307 |     _operators = {
308 |         '~=': '_match_compatible',
309 |         '<': '_match_lt',
310 |         '>': '_match_gt',
311 |         '<=': '_match_le',
312 |         '>=': '_match_ge',
313 |         '==': '_match_eq',
314 |         '===': '_match_arbitrary',
315 |         '!=': '_match_ne',
316 |     }
317 | 
318 |     def _adjust_local(self, version, constraint, prefix):
319 |         if prefix:
320 |             strip_local = '+' not in constraint and version._parts[-1]
321 |         else:
322 |             # both constraint and version are
323 |             # NormalizedVersion instances.
324 |             # If constraint does not have a local component,
325 |             # ensure the version doesn't, either.
326 |             strip_local = not constraint._parts[-1] and version._parts[-1]
327 |         if strip_local:
328 |             s = version._string.split('+', 1)[0]
329 |             version = self.version_class(s)
330 |         return version, constraint
331 | 
332 |     def _match_lt(self, version, constraint, prefix):
333 |         version, constraint = self._adjust_local(version, constraint, prefix)
334 |         if version >= constraint:
335 |             return False
336 |         release_clause = constraint._release_clause
337 |         pfx = '.'.join([str(i) for i in release_clause])
338 |         return not _match_prefix(version, pfx)
339 | 
340 |     def _match_gt(self, version, constraint, prefix):
341 |         version, constraint = self._adjust_local(version, constraint, prefix)
342 |         if version <= constraint:
343 |             return False
344 |         release_clause = constraint._release_clause
345 |         pfx = '.'.join([str(i) for i in release_clause])
346 |         return not _match_prefix(version, pfx)
347 | 
348 |     def _match_le(self, version, constraint, prefix):
349 |         version, constraint = self._adjust_local(version, constraint, prefix)
350 |         return version <= constraint
351 | 
352 |     def _match_ge(self, version, constraint, prefix):
353 |         version, constraint = self._adjust_local(version, constraint, prefix)
354 |         return version >= constraint
355 | 
356 |     def _match_eq(self, version, constraint, prefix):
357 |         version, constraint = self._adjust_local(version, constraint, prefix)
358 |         if not prefix:
359 |             result = (version == constraint)
360 |         else:
361 |             result = _match_prefix(version, constraint)
362 |         return result
363 | 
364 |     def _match_arbitrary(self, version, constraint, prefix):
365 |         return str(version) == str(constraint)
366 | 
367 |     def _match_ne(self, version, constraint, prefix):
368 |         version, constraint = self._adjust_local(version, constraint, prefix)
369 |         if not prefix:
370 |             result = (version != constraint)
371 |         else:
372 |             result = not _match_prefix(version, constraint)
373 |         return result
374 | 
375 |     def _match_compatible(self, version, constraint, prefix):
376 |         version, constraint = self._adjust_local(version, constraint, prefix)
377 |         if version == constraint:
378 |             return True
379 |         if version < constraint:
380 |             return False
381 | #        if not prefix:
382 | #            return True
383 |         release_clause = constraint._release_clause
384 |         if len(release_clause) > 1:
385 |             release_clause = release_clause[:-1]
386 |         pfx = '.'.join([str(i) for i in release_clause])
387 |         return _match_prefix(version, pfx)
388 | 
389 | 
390 | _REPLACEMENTS = (
391 |     (re.compile('[.+-]$'), ''),                     # remove trailing puncts
392 |     (re.compile(r'^[.](\d)'), r'0.\1'),             # .N -> 0.N at start
393 |     (re.compile('^[.-]'), ''),                      # remove leading puncts
394 |     (re.compile(r'^\((.*)\)$'), r'\1'),             # remove parentheses
395 |     (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'),    # remove leading v(ersion)
396 |     (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'),        # remove leading v(ersion)
397 |     (re.compile('[.]{2,}'), '.'),                   # multiple runs of '.'
398 |     (re.compile(r'\b(alfa|apha)\b'), 'alpha'),      # misspelt alpha
399 |     (re.compile(r'\b(pre-alpha|prealpha)\b'),
400 |         'pre.alpha'),                               # standardise
401 |     (re.compile(r'\(beta\)$'), 'beta'),             # remove parentheses
402 | )
403 | 
404 | _SUFFIX_REPLACEMENTS = (
405 |     (re.compile('^[:~._+-]+'), ''),                   # remove leading puncts
406 |     (re.compile('[,*")([\\]]'), ''),                  # remove unwanted chars
407 |     (re.compile('[~:+_ -]'), '.'),                    # replace illegal chars
408 |     (re.compile('[.]{2,}'), '.'),                   # multiple runs of '.'
409 |     (re.compile(r'\.$'), ''),                       # trailing '.'
410 | )
411 | 
412 | _NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)')
413 | 
414 | 
415 | def _suggest_semantic_version(s):
416 |     """
417 |     Try to suggest a semantic form for a version for which
418 |     _suggest_normalized_version couldn't come up with anything.
419 |     """
420 |     result = s.strip().lower()
421 |     for pat, repl in _REPLACEMENTS:
422 |         result = pat.sub(repl, result)
423 |     if not result:
424 |         result = '0.0.0'
425 | 
426 |     # Now look for numeric prefix, and separate it out from
427 |     # the rest.
428 |     # import pdb; pdb.set_trace()
429 |     m = _NUMERIC_PREFIX.match(result)
430 |     if not m:
431 |         prefix = '0.0.0'
432 |         suffix = result
433 |     else:
434 |         prefix = m.groups()[0].split('.')
435 |         prefix = [int(i) for i in prefix]
436 |         while len(prefix) < 3:
437 |             prefix.append(0)
438 |         if len(prefix) == 3:
439 |             suffix = result[m.end():]
440 |         else:
441 |             suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():]
442 |             prefix = prefix[:3]
443 |         prefix = '.'.join([str(i) for i in prefix])
444 |         suffix = suffix.strip()
445 |     if suffix:
446 |         # import pdb; pdb.set_trace()
447 |         # massage the suffix.
448 |         for pat, repl in _SUFFIX_REPLACEMENTS:
449 |             suffix = pat.sub(repl, suffix)
450 | 
451 |     if not suffix:
452 |         result = prefix
453 |     else:
454 |         sep = '-' if 'dev' in suffix else '+'
455 |         result = prefix + sep + suffix
456 |     if not is_semver(result):
457 |         result = None
458 |     return result
459 | 
460 | 
461 | def _suggest_normalized_version(s):
462 |     """Suggest a normalized version close to the given version string.
463 | 
464 |     If you have a version string that isn't rational (i.e. NormalizedVersion
465 |     doesn't like it) then you might be able to get an equivalent (or close)
466 |     rational version from this function.
467 | 
468 |     This does a number of simple normalizations to the given string, based
469 |     on observation of versions currently in use on PyPI. Given a dump of
470 |     those version during PyCon 2009, 4287 of them:
471 |     - 2312 (53.93%) match NormalizedVersion without change
472 |       with the automatic suggestion
473 |     - 3474 (81.04%) match when using this suggestion method
474 | 
475 |     @param s {str} An irrational version string.
476 |     @returns A rational version string, or None, if couldn't determine one.
477 |     """
478 |     try:
479 |         _normalized_key(s)
480 |         return s   # already rational
481 |     except UnsupportedVersionError:
482 |         pass
483 | 
484 |     rs = s.lower()
485 | 
486 |     # part of this could use maketrans
487 |     for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'),
488 |                        ('beta', 'b'), ('rc', 'c'), ('-final', ''),
489 |                        ('-pre', 'c'),
490 |                        ('-release', ''), ('.release', ''), ('-stable', ''),
491 |                        ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''),
492 |                        ('final', '')):
493 |         rs = rs.replace(orig, repl)
494 | 
495 |     # if something ends with dev or pre, we add a 0
496 |     rs = re.sub(r"pre$", r"pre0", rs)
497 |     rs = re.sub(r"dev$", r"dev0", rs)
498 | 
499 |     # if we have something like "b-2" or "a.2" at the end of the
500 |     # version, that is probably beta, alpha, etc
501 |     # let's remove the dash or dot
502 |     rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs)
503 | 
504 |     # 1.0-dev-r371 -> 1.0.dev371
505 |     # 0.1-dev-r79 -> 0.1.dev79
506 |     rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs)
507 | 
508 |     # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1
509 |     rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs)
510 | 
511 |     # Clean: v0.3, v1.0
512 |     if rs.startswith('v'):
513 |         rs = rs[1:]
514 | 
515 |     # Clean leading '0's on numbers.
516 |     # TODO: unintended side-effect on, e.g., "2003.05.09"
517 |     # PyPI stats: 77 (~2%) better
518 |     rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs)
519 | 
520 |     # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers
521 |     # zero.
522 |     # PyPI stats: 245 (7.56%) better
523 |     rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs)
524 | 
525 |     # the 'dev-rNNN' tag is a dev tag
526 |     rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs)
527 | 
528 |     # clean the - when used as a pre delimiter
529 |     rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs)
530 | 
531 |     # a terminal "dev" or "devel" can be changed into ".dev0"
532 |     rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs)
533 | 
534 |     # a terminal "dev" can be changed into ".dev0"
535 |     rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs)
536 | 
537 |     # a terminal "final" or "stable" can be removed
538 |     rs = re.sub(r"(final|stable)$", "", rs)
539 | 
540 |     # The 'r' and the '-' tags are post release tags
541 |     #   0.4a1.r10       ->  0.4a1.post10
542 |     #   0.9.33-17222    ->  0.9.33.post17222
543 |     #   0.9.33-r17222   ->  0.9.33.post17222
544 |     rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs)
545 | 
546 |     # Clean 'r' instead of 'dev' usage:
547 |     #   0.9.33+r17222   ->  0.9.33.dev17222
548 |     #   1.0dev123       ->  1.0.dev123
549 |     #   1.0.git123      ->  1.0.dev123
550 |     #   1.0.bzr123      ->  1.0.dev123
551 |     #   0.1a0dev.123    ->  0.1a0.dev123
552 |     # PyPI stats:  ~150 (~4%) better
553 |     rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs)
554 | 
555 |     # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage:
556 |     #   0.2.pre1        ->  0.2c1
557 |     #   0.2-c1         ->  0.2c1
558 |     #   1.0preview123   ->  1.0c123
559 |     # PyPI stats: ~21 (0.62%) better
560 |     rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs)
561 | 
562 |     # Tcl/Tk uses "px" for their post release markers
563 |     rs = re.sub(r"p(\d+)$", r".post\1", rs)
564 | 
565 |     try:
566 |         _normalized_key(rs)
567 |     except UnsupportedVersionError:
568 |         rs = None
569 |     return rs
570 | 
571 | #
572 | #   Legacy version processing (distribute-compatible)
573 | #
574 | 
575 | 
576 | _VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I)
577 | _VERSION_REPLACE = {
578 |     'pre': 'c',
579 |     'preview': 'c',
580 |     '-': 'final-',
581 |     'rc': 'c',
582 |     'dev': '@',
583 |     '': None,
584 |     '.': None,
585 | }
586 | 
587 | 
588 | def _legacy_key(s):
589 |     def get_parts(s):
590 |         result = []
591 |         for p in _VERSION_PART.split(s.lower()):
592 |             p = _VERSION_REPLACE.get(p, p)
593 |             if p:
594 |                 if '0' <= p[:1] <= '9':
595 |                     p = p.zfill(8)
596 |                 else:
597 |                     p = '*' + p
598 |                 result.append(p)
599 |         result.append('*final')
600 |         return result
601 | 
602 |     result = []
603 |     for p in get_parts(s):
604 |         if p.startswith('*'):
605 |             if p < '*final':
606 |                 while result and result[-1] == '*final-':
607 |                     result.pop()
608 |             while result and result[-1] == '00000000':
609 |                 result.pop()
610 |         result.append(p)
611 |     return tuple(result)
612 | 
613 | 
614 | class LegacyVersion(Version):
615 |     def parse(self, s):
616 |         return _legacy_key(s)
617 | 
618 |     @property
619 |     def is_prerelease(self):
620 |         result = False
621 |         for x in self._parts:
622 |             if (isinstance(x, string_types) and x.startswith('*') and
623 |                     x < '*final'):
624 |                 result = True
625 |                 break
626 |         return result
627 | 
628 | 
629 | class LegacyMatcher(Matcher):
630 |     version_class = LegacyVersion
631 | 
632 |     _operators = dict(Matcher._operators)
633 |     _operators['~='] = '_match_compatible'
634 | 
635 |     numeric_re = re.compile(r'^(\d+(\.\d+)*)')
636 | 
637 |     def _match_compatible(self, version, constraint, prefix):
638 |         if version < constraint:
639 |             return False
640 |         m = self.numeric_re.match(str(constraint))
641 |         if not m:
642 |             logger.warning('Cannot compute compatible match for version %s '
643 |                            ' and constraint %s', version, constraint)
644 |             return True
645 |         s = m.groups()[0]
646 |         if '.' in s:
647 |             s = s.rsplit('.', 1)[0]
648 |         return _match_prefix(version, s)
649 | 
650 | #
651 | #   Semantic versioning
652 | #
653 | 
654 | 
655 | _SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)'
656 |                         r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?'
657 |                         r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I)
658 | 
659 | 
660 | def is_semver(s):
661 |     return _SEMVER_RE.match(s)
662 | 
663 | 
664 | def _semantic_key(s):
665 |     def make_tuple(s, absent):
666 |         if s is None:
667 |             result = (absent,)
668 |         else:
669 |             parts = s[1:].split('.')
670 |             # We can't compare ints and strings on Python 3, so fudge it
671 |             # by zero-filling numeric values so simulate a numeric comparison
672 |             result = tuple([p.zfill(8) if p.isdigit() else p for p in parts])
673 |         return result
674 | 
675 |     m = is_semver(s)
676 |     if not m:
677 |         raise UnsupportedVersionError(s)
678 |     groups = m.groups()
679 |     major, minor, patch = [int(i) for i in groups[:3]]
680 |     # choose the '|' and '*' so that versions sort correctly
681 |     pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*')
682 |     return (major, minor, patch), pre, build
683 | 
684 | 
685 | class SemanticVersion(Version):
686 |     def parse(self, s):
687 |         return _semantic_key(s)
688 | 
689 |     @property
690 |     def is_prerelease(self):
691 |         return self._parts[1][0] != '|'
692 | 
693 | 
694 | class SemanticMatcher(Matcher):
695 |     version_class = SemanticVersion
696 | 
697 | 
698 | class VersionScheme(object):
699 |     def __init__(self, key, matcher, suggester=None):
700 |         self.key = key
701 |         self.matcher = matcher
702 |         self.suggester = suggester
703 | 
704 |     def is_valid_version(self, s):
705 |         try:
706 |             self.matcher.version_class(s)
707 |             result = True
708 |         except UnsupportedVersionError:
709 |             result = False
710 |         return result
711 | 
712 |     def is_valid_matcher(self, s):
713 |         try:
714 |             self.matcher(s)
715 |             result = True
716 |         except UnsupportedVersionError:
717 |             result = False
718 |         return result
719 | 
720 |     def is_valid_constraint_list(self, s):
721 |         """
722 |         Used for processing some metadata fields
723 |         """
724 |         # See issue #140. Be tolerant of a single trailing comma.
725 |         if s.endswith(','):
726 |             s = s[:-1]
727 |         return self.is_valid_matcher('dummy_name (%s)' % s)
728 | 
729 |     def suggest(self, s):
730 |         if self.suggester is None:
731 |             result = None
732 |         else:
733 |             result = self.suggester(s)
734 |         return result
735 | 
736 | 
737 | _SCHEMES = {
738 |     'normalized': VersionScheme(_normalized_key, NormalizedMatcher,
739 |                                 _suggest_normalized_version),
740 |     'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s),
741 |     'semantic': VersionScheme(_semantic_key, SemanticMatcher,
742 |                               _suggest_semantic_version),
743 | }
744 | 
745 | _SCHEMES['default'] = _SCHEMES['normalized']
746 | 
747 | 
748 | def get_scheme(name):
749 |     if name not in _SCHEMES:
750 |         raise ValueError('unknown scheme name: %r' % name)
751 |     return _SCHEMES[name]
752 | 
```
Page 79/168FirstPrevNextLast