This is page 19 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/cli/index_command.py:
--------------------------------------------------------------------------------
```python
1 | """
2 | Contains command classes which may interact with an index / the network.
3 |
4 | Unlike its sister module, req_command, this module still uses lazy imports
5 | so commands which don't always hit the network (e.g. list w/o --outdated or
6 | --uptodate) don't need waste time importing PipSession and friends.
7 | """
8 |
9 | import logging
10 | import os
11 | import sys
12 | from optparse import Values
13 | from typing import TYPE_CHECKING, List, Optional
14 |
15 | from pip._vendor import certifi
16 |
17 | from pip._internal.cli.base_command import Command
18 | from pip._internal.cli.command_context import CommandContextMixIn
19 |
20 | if TYPE_CHECKING:
21 | from ssl import SSLContext
22 |
23 | from pip._internal.network.session import PipSession
24 |
25 | logger = logging.getLogger(__name__)
26 |
27 |
28 | def _create_truststore_ssl_context() -> Optional["SSLContext"]:
29 | if sys.version_info < (3, 10):
30 | logger.debug("Disabling truststore because Python version isn't 3.10+")
31 | return None
32 |
33 | try:
34 | import ssl
35 | except ImportError:
36 | logger.warning("Disabling truststore since ssl support is missing")
37 | return None
38 |
39 | try:
40 | from pip._vendor import truststore
41 | except ImportError:
42 | logger.warning("Disabling truststore because platform isn't supported")
43 | return None
44 |
45 | ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
46 | ctx.load_verify_locations(certifi.where())
47 | return ctx
48 |
49 |
50 | class SessionCommandMixin(CommandContextMixIn):
51 | """
52 | A class mixin for command classes needing _build_session().
53 | """
54 |
55 | def __init__(self) -> None:
56 | super().__init__()
57 | self._session: Optional["PipSession"] = None
58 |
59 | @classmethod
60 | def _get_index_urls(cls, options: Values) -> Optional[List[str]]:
61 | """Return a list of index urls from user-provided options."""
62 | index_urls = []
63 | if not getattr(options, "no_index", False):
64 | url = getattr(options, "index_url", None)
65 | if url:
66 | index_urls.append(url)
67 | urls = getattr(options, "extra_index_urls", None)
68 | if urls:
69 | index_urls.extend(urls)
70 | # Return None rather than an empty list
71 | return index_urls or None
72 |
73 | def get_default_session(self, options: Values) -> "PipSession":
74 | """Get a default-managed session."""
75 | if self._session is None:
76 | self._session = self.enter_context(self._build_session(options))
77 | # there's no type annotation on requests.Session, so it's
78 | # automatically ContextManager[Any] and self._session becomes Any,
79 | # then https://github.com/python/mypy/issues/7696 kicks in
80 | assert self._session is not None
81 | return self._session
82 |
83 | def _build_session(
84 | self,
85 | options: Values,
86 | retries: Optional[int] = None,
87 | timeout: Optional[int] = None,
88 | ) -> "PipSession":
89 | from pip._internal.network.session import PipSession
90 |
91 | cache_dir = options.cache_dir
92 | assert not cache_dir or os.path.isabs(cache_dir)
93 |
94 | if "legacy-certs" not in options.deprecated_features_enabled:
95 | ssl_context = _create_truststore_ssl_context()
96 | else:
97 | ssl_context = None
98 |
99 | session = PipSession(
100 | cache=os.path.join(cache_dir, "http-v2") if cache_dir else None,
101 | retries=retries if retries is not None else options.retries,
102 | trusted_hosts=options.trusted_hosts,
103 | index_urls=self._get_index_urls(options),
104 | ssl_context=ssl_context,
105 | )
106 |
107 | # Handle custom ca-bundles from the user
108 | if options.cert:
109 | session.verify = options.cert
110 |
111 | # Handle SSL client certificate
112 | if options.client_cert:
113 | session.cert = options.client_cert
114 |
115 | # Handle timeouts
116 | if options.timeout or timeout:
117 | session.timeout = timeout if timeout is not None else options.timeout
118 |
119 | # Handle configured proxies
120 | if options.proxy:
121 | session.proxies = {
122 | "http": options.proxy,
123 | "https": options.proxy,
124 | }
125 | session.trust_env = False
126 |
127 | # Determine if we can prompt the user for authentication or not
128 | session.auth.prompting = not options.no_input
129 | session.auth.keyring_provider = options.keyring_provider
130 |
131 | return session
132 |
133 |
134 | def _pip_self_version_check(session: "PipSession", options: Values) -> None:
135 | from pip._internal.self_outdated_check import pip_self_version_check as check
136 |
137 | check(session, options)
138 |
139 |
140 | class IndexGroupCommand(Command, SessionCommandMixin):
141 | """
142 | Abstract base class for commands with the index_group options.
143 |
144 | This also corresponds to the commands that permit the pip version check.
145 | """
146 |
147 | def handle_pip_version_check(self, options: Values) -> None:
148 | """
149 | Do the pip version check if not disabled.
150 |
151 | This overrides the default behavior of not doing the check.
152 | """
153 | # Make sure the index_group options are present.
154 | assert hasattr(options, "no_index")
155 |
156 | if options.disable_pip_version_check or options.no_index:
157 | return
158 |
159 | try:
160 | # Otherwise, check if we're using the latest version of pip available.
161 | session = self._build_session(
162 | options,
163 | retries=0,
164 | timeout=min(5, options.timeout),
165 | )
166 | with session:
167 | _pip_self_version_check(session, options)
168 | except Exception:
169 | logger.warning("There was an error checking the latest version of pip.")
170 | logger.debug("See below for error", exc_info=True)
171 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/urllib3/_base_connection.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import typing
4 |
5 | from .util.connection import _TYPE_SOCKET_OPTIONS
6 | from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT
7 | from .util.url import Url
8 |
9 | _TYPE_BODY = typing.Union[bytes, typing.IO[typing.Any], typing.Iterable[bytes], str]
10 |
11 |
12 | class ProxyConfig(typing.NamedTuple):
13 | ssl_context: ssl.SSLContext | None
14 | use_forwarding_for_https: bool
15 | assert_hostname: None | str | typing.Literal[False]
16 | assert_fingerprint: str | None
17 |
18 |
19 | class _ResponseOptions(typing.NamedTuple):
20 | # TODO: Remove this in favor of a better
21 | # HTTP request/response lifecycle tracking.
22 | request_method: str
23 | request_url: str
24 | preload_content: bool
25 | decode_content: bool
26 | enforce_content_length: bool
27 |
28 |
29 | if typing.TYPE_CHECKING:
30 | import ssl
31 | from typing import Protocol
32 |
33 | from .response import BaseHTTPResponse
34 |
35 | class BaseHTTPConnection(Protocol):
36 | default_port: typing.ClassVar[int]
37 | default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
38 |
39 | host: str
40 | port: int
41 | timeout: None | (
42 | float
43 | ) # Instance doesn't store _DEFAULT_TIMEOUT, must be resolved.
44 | blocksize: int
45 | source_address: tuple[str, int] | None
46 | socket_options: _TYPE_SOCKET_OPTIONS | None
47 |
48 | proxy: Url | None
49 | proxy_config: ProxyConfig | None
50 |
51 | is_verified: bool
52 | proxy_is_verified: bool | None
53 |
54 | def __init__(
55 | self,
56 | host: str,
57 | port: int | None = None,
58 | *,
59 | timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
60 | source_address: tuple[str, int] | None = None,
61 | blocksize: int = 8192,
62 | socket_options: _TYPE_SOCKET_OPTIONS | None = ...,
63 | proxy: Url | None = None,
64 | proxy_config: ProxyConfig | None = None,
65 | ) -> None:
66 | ...
67 |
68 | def set_tunnel(
69 | self,
70 | host: str,
71 | port: int | None = None,
72 | headers: typing.Mapping[str, str] | None = None,
73 | scheme: str = "http",
74 | ) -> None:
75 | ...
76 |
77 | def connect(self) -> None:
78 | ...
79 |
80 | def request(
81 | self,
82 | method: str,
83 | url: str,
84 | body: _TYPE_BODY | None = None,
85 | headers: typing.Mapping[str, str] | None = None,
86 | # We know *at least* botocore is depending on the order of the
87 | # first 3 parameters so to be safe we only mark the later ones
88 | # as keyword-only to ensure we have space to extend.
89 | *,
90 | chunked: bool = False,
91 | preload_content: bool = True,
92 | decode_content: bool = True,
93 | enforce_content_length: bool = True,
94 | ) -> None:
95 | ...
96 |
97 | def getresponse(self) -> BaseHTTPResponse:
98 | ...
99 |
100 | def close(self) -> None:
101 | ...
102 |
103 | @property
104 | def is_closed(self) -> bool:
105 | """Whether the connection either is brand new or has been previously closed.
106 | If this property is True then both ``is_connected`` and ``has_connected_to_proxy``
107 | properties must be False.
108 | """
109 |
110 | @property
111 | def is_connected(self) -> bool:
112 | """Whether the connection is actively connected to any origin (proxy or target)"""
113 |
114 | @property
115 | def has_connected_to_proxy(self) -> bool:
116 | """Whether the connection has successfully connected to its proxy.
117 | This returns False if no proxy is in use. Used to determine whether
118 | errors are coming from the proxy layer or from tunnelling to the target origin.
119 | """
120 |
121 | class BaseHTTPSConnection(BaseHTTPConnection, Protocol):
122 | default_port: typing.ClassVar[int]
123 | default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
124 |
125 | # Certificate verification methods
126 | cert_reqs: int | str | None
127 | assert_hostname: None | str | typing.Literal[False]
128 | assert_fingerprint: str | None
129 | ssl_context: ssl.SSLContext | None
130 |
131 | # Trusted CAs
132 | ca_certs: str | None
133 | ca_cert_dir: str | None
134 | ca_cert_data: None | str | bytes
135 |
136 | # TLS version
137 | ssl_minimum_version: int | None
138 | ssl_maximum_version: int | None
139 | ssl_version: int | str | None # Deprecated
140 |
141 | # Client certificates
142 | cert_file: str | None
143 | key_file: str | None
144 | key_password: str | None
145 |
146 | def __init__(
147 | self,
148 | host: str,
149 | port: int | None = None,
150 | *,
151 | timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
152 | source_address: tuple[str, int] | None = None,
153 | blocksize: int = 16384,
154 | socket_options: _TYPE_SOCKET_OPTIONS | None = ...,
155 | proxy: Url | None = None,
156 | proxy_config: ProxyConfig | None = None,
157 | cert_reqs: int | str | None = None,
158 | assert_hostname: None | str | typing.Literal[False] = None,
159 | assert_fingerprint: str | None = None,
160 | server_hostname: str | None = None,
161 | ssl_context: ssl.SSLContext | None = None,
162 | ca_certs: str | None = None,
163 | ca_cert_dir: str | None = None,
164 | ca_cert_data: None | str | bytes = None,
165 | ssl_minimum_version: int | None = None,
166 | ssl_maximum_version: int | None = None,
167 | ssl_version: int | str | None = None, # Deprecated
168 | cert_file: str | None = None,
169 | key_file: str | None = None,
170 | key_password: str | None = None,
171 | ) -> None:
172 | ...
173 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/datastructures/range.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 |
4 | class IfRange:
5 | """Very simple object that represents the `If-Range` header in parsed
6 | form. It will either have neither a etag or date or one of either but
7 | never both.
8 |
9 | .. versionadded:: 0.7
10 | """
11 |
12 | def __init__(self, etag=None, date=None):
13 | #: The etag parsed and unquoted. Ranges always operate on strong
14 | #: etags so the weakness information is not necessary.
15 | self.etag = etag
16 | #: The date in parsed format or `None`.
17 | self.date = date
18 |
19 | def to_header(self):
20 | """Converts the object back into an HTTP header."""
21 | if self.date is not None:
22 | return http.http_date(self.date)
23 | if self.etag is not None:
24 | return http.quote_etag(self.etag)
25 | return ""
26 |
27 | def __str__(self):
28 | return self.to_header()
29 |
30 | def __repr__(self):
31 | return f"<{type(self).__name__} {str(self)!r}>"
32 |
33 |
34 | class Range:
35 | """Represents a ``Range`` header. All methods only support only
36 | bytes as the unit. Stores a list of ranges if given, but the methods
37 | only work if only one range is provided.
38 |
39 | :raise ValueError: If the ranges provided are invalid.
40 |
41 | .. versionchanged:: 0.15
42 | The ranges passed in are validated.
43 |
44 | .. versionadded:: 0.7
45 | """
46 |
47 | def __init__(self, units, ranges):
48 | #: The units of this range. Usually "bytes".
49 | self.units = units
50 | #: A list of ``(begin, end)`` tuples for the range header provided.
51 | #: The ranges are non-inclusive.
52 | self.ranges = ranges
53 |
54 | for start, end in ranges:
55 | if start is None or (end is not None and (start < 0 or start >= end)):
56 | raise ValueError(f"{(start, end)} is not a valid range.")
57 |
58 | def range_for_length(self, length):
59 | """If the range is for bytes, the length is not None and there is
60 | exactly one range and it is satisfiable it returns a ``(start, stop)``
61 | tuple, otherwise `None`.
62 | """
63 | if self.units != "bytes" or length is None or len(self.ranges) != 1:
64 | return None
65 | start, end = self.ranges[0]
66 | if end is None:
67 | end = length
68 | if start < 0:
69 | start += length
70 | if http.is_byte_range_valid(start, end, length):
71 | return start, min(end, length)
72 | return None
73 |
74 | def make_content_range(self, length):
75 | """Creates a :class:`~werkzeug.datastructures.ContentRange` object
76 | from the current range and given content length.
77 | """
78 | rng = self.range_for_length(length)
79 | if rng is not None:
80 | return ContentRange(self.units, rng[0], rng[1], length)
81 | return None
82 |
83 | def to_header(self):
84 | """Converts the object back into an HTTP header."""
85 | ranges = []
86 | for begin, end in self.ranges:
87 | if end is None:
88 | ranges.append(f"{begin}-" if begin >= 0 else str(begin))
89 | else:
90 | ranges.append(f"{begin}-{end - 1}")
91 | return f"{self.units}={','.join(ranges)}"
92 |
93 | def to_content_range_header(self, length):
94 | """Converts the object into `Content-Range` HTTP header,
95 | based on given length
96 | """
97 | range = self.range_for_length(length)
98 | if range is not None:
99 | return f"{self.units} {range[0]}-{range[1] - 1}/{length}"
100 | return None
101 |
102 | def __str__(self):
103 | return self.to_header()
104 |
105 | def __repr__(self):
106 | return f"<{type(self).__name__} {str(self)!r}>"
107 |
108 |
109 | def _callback_property(name):
110 | def fget(self):
111 | return getattr(self, name)
112 |
113 | def fset(self, value):
114 | setattr(self, name, value)
115 | if self.on_update is not None:
116 | self.on_update(self)
117 |
118 | return property(fget, fset)
119 |
120 |
121 | class ContentRange:
122 | """Represents the content range header.
123 |
124 | .. versionadded:: 0.7
125 | """
126 |
127 | def __init__(self, units, start, stop, length=None, on_update=None):
128 | assert http.is_byte_range_valid(start, stop, length), "Bad range provided"
129 | self.on_update = on_update
130 | self.set(start, stop, length, units)
131 |
132 | #: The units to use, usually "bytes"
133 | units = _callback_property("_units")
134 | #: The start point of the range or `None`.
135 | start = _callback_property("_start")
136 | #: The stop point of the range (non-inclusive) or `None`. Can only be
137 | #: `None` if also start is `None`.
138 | stop = _callback_property("_stop")
139 | #: The length of the range or `None`.
140 | length = _callback_property("_length")
141 |
142 | def set(self, start, stop, length=None, units="bytes"):
143 | """Simple method to update the ranges."""
144 | assert http.is_byte_range_valid(start, stop, length), "Bad range provided"
145 | self._units = units
146 | self._start = start
147 | self._stop = stop
148 | self._length = length
149 | if self.on_update is not None:
150 | self.on_update(self)
151 |
152 | def unset(self):
153 | """Sets the units to `None` which indicates that the header should
154 | no longer be used.
155 | """
156 | self.set(None, None, units=None)
157 |
158 | def to_header(self):
159 | if self.units is None:
160 | return ""
161 | if self.length is None:
162 | length = "*"
163 | else:
164 | length = self.length
165 | if self.start is None:
166 | return f"{self.units} */{length}"
167 | return f"{self.units} {self.start}-{self.stop - 1}/{length}"
168 |
169 | def __bool__(self):
170 | return self.units is not None
171 |
172 | def __str__(self):
173 | return self.to_header()
174 |
175 | def __repr__(self):
176 | return f"<{type(self).__name__} {str(self)!r}>"
177 |
178 |
179 | # circular dependencies
180 | from .. import http
181 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py:
--------------------------------------------------------------------------------
```python
1 | """The match_hostname() function from Python 3.3.3, essential when using SSL."""
2 |
3 | # Note: This file is under the PSF license as the code comes from the python
4 | # stdlib. http://docs.python.org/3/license.html
5 |
6 | import re
7 | import sys
8 |
9 | # ipaddress has been backported to 2.6+ in pypi. If it is installed on the
10 | # system, use it to handle IPAddress ServerAltnames (this was added in
11 | # python-3.5) otherwise only do DNS matching. This allows
12 | # util.ssl_match_hostname to continue to be used in Python 2.7.
13 | try:
14 | import ipaddress
15 | except ImportError:
16 | ipaddress = None
17 |
18 | __version__ = "3.5.0.1"
19 |
20 |
21 | class CertificateError(ValueError):
22 | pass
23 |
24 |
25 | def _dnsname_match(dn, hostname, max_wildcards=1):
26 | """Matching according to RFC 6125, section 6.4.3
27 |
28 | http://tools.ietf.org/html/rfc6125#section-6.4.3
29 | """
30 | pats = []
31 | if not dn:
32 | return False
33 |
34 | # Ported from python3-syntax:
35 | # leftmost, *remainder = dn.split(r'.')
36 | parts = dn.split(r".")
37 | leftmost = parts[0]
38 | remainder = parts[1:]
39 |
40 | wildcards = leftmost.count("*")
41 | if wildcards > max_wildcards:
42 | # Issue #17980: avoid denials of service by refusing more
43 | # than one wildcard per fragment. A survey of established
44 | # policy among SSL implementations showed it to be a
45 | # reasonable choice.
46 | raise CertificateError(
47 | "too many wildcards in certificate DNS name: " + repr(dn)
48 | )
49 |
50 | # speed up common case w/o wildcards
51 | if not wildcards:
52 | return dn.lower() == hostname.lower()
53 |
54 | # RFC 6125, section 6.4.3, subitem 1.
55 | # The client SHOULD NOT attempt to match a presented identifier in which
56 | # the wildcard character comprises a label other than the left-most label.
57 | if leftmost == "*":
58 | # When '*' is a fragment by itself, it matches a non-empty dotless
59 | # fragment.
60 | pats.append("[^.]+")
61 | elif leftmost.startswith("xn--") or hostname.startswith("xn--"):
62 | # RFC 6125, section 6.4.3, subitem 3.
63 | # The client SHOULD NOT attempt to match a presented identifier
64 | # where the wildcard character is embedded within an A-label or
65 | # U-label of an internationalized domain name.
66 | pats.append(re.escape(leftmost))
67 | else:
68 | # Otherwise, '*' matches any dotless string, e.g. www*
69 | pats.append(re.escape(leftmost).replace(r"\*", "[^.]*"))
70 |
71 | # add the remaining fragments, ignore any wildcards
72 | for frag in remainder:
73 | pats.append(re.escape(frag))
74 |
75 | pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE)
76 | return pat.match(hostname)
77 |
78 |
79 | def _to_unicode(obj):
80 | if isinstance(obj, str) and sys.version_info < (3,):
81 | # ignored flake8 # F821 to support python 2.7 function
82 | obj = unicode(obj, encoding="ascii", errors="strict") # noqa: F821
83 | return obj
84 |
85 |
86 | def _ipaddress_match(ipname, host_ip):
87 | """Exact matching of IP addresses.
88 |
89 | RFC 6125 explicitly doesn't define an algorithm for this
90 | (section 1.7.2 - "Out of Scope").
91 | """
92 | # OpenSSL may add a trailing newline to a subjectAltName's IP address
93 | # Divergence from upstream: ipaddress can't handle byte str
94 | ip = ipaddress.ip_address(_to_unicode(ipname).rstrip())
95 | return ip == host_ip
96 |
97 |
98 | def match_hostname(cert, hostname):
99 | """Verify that *cert* (in decoded format as returned by
100 | SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
101 | rules are followed, but IP addresses are not accepted for *hostname*.
102 |
103 | CertificateError is raised on failure. On success, the function
104 | returns nothing.
105 | """
106 | if not cert:
107 | raise ValueError(
108 | "empty or no certificate, match_hostname needs a "
109 | "SSL socket or SSL context with either "
110 | "CERT_OPTIONAL or CERT_REQUIRED"
111 | )
112 | try:
113 | # Divergence from upstream: ipaddress can't handle byte str
114 | host_ip = ipaddress.ip_address(_to_unicode(hostname))
115 | except (UnicodeError, ValueError):
116 | # ValueError: Not an IP address (common case)
117 | # UnicodeError: Divergence from upstream: Have to deal with ipaddress not taking
118 | # byte strings. addresses should be all ascii, so we consider it not
119 | # an ipaddress in this case
120 | host_ip = None
121 | except AttributeError:
122 | # Divergence from upstream: Make ipaddress library optional
123 | if ipaddress is None:
124 | host_ip = None
125 | else: # Defensive
126 | raise
127 | dnsnames = []
128 | san = cert.get("subjectAltName", ())
129 | for key, value in san:
130 | if key == "DNS":
131 | if host_ip is None and _dnsname_match(value, hostname):
132 | return
133 | dnsnames.append(value)
134 | elif key == "IP Address":
135 | if host_ip is not None and _ipaddress_match(value, host_ip):
136 | return
137 | dnsnames.append(value)
138 | if not dnsnames:
139 | # The subject is only checked when there is no dNSName entry
140 | # in subjectAltName
141 | for sub in cert.get("subject", ()):
142 | for key, value in sub:
143 | # XXX according to RFC 2818, the most specific Common Name
144 | # must be used.
145 | if key == "commonName":
146 | if _dnsname_match(value, hostname):
147 | return
148 | dnsnames.append(value)
149 | if len(dnsnames) > 1:
150 | raise CertificateError(
151 | "hostname %r "
152 | "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames)))
153 | )
154 | elif len(dnsnames) == 1:
155 | raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0]))
156 | else:
157 | raise CertificateError(
158 | "no appropriate commonName or subjectAltName fields were found"
159 | )
160 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/urllib3/util/ssl_match_hostname.py:
--------------------------------------------------------------------------------
```python
1 | """The match_hostname() function from Python 3.5, essential when using SSL."""
2 |
3 | # Note: This file is under the PSF license as the code comes from the python
4 | # stdlib. http://docs.python.org/3/license.html
5 | # It is modified to remove commonName support.
6 |
7 | from __future__ import annotations
8 |
9 | import ipaddress
10 | import re
11 | import typing
12 | from ipaddress import IPv4Address, IPv6Address
13 |
14 | if typing.TYPE_CHECKING:
15 | from .ssl_ import _TYPE_PEER_CERT_RET_DICT
16 |
17 | __version__ = "3.5.0.1"
18 |
19 |
20 | class CertificateError(ValueError):
21 | pass
22 |
23 |
24 | def _dnsname_match(
25 | dn: typing.Any, hostname: str, max_wildcards: int = 1
26 | ) -> typing.Match[str] | None | bool:
27 | """Matching according to RFC 6125, section 6.4.3
28 |
29 | http://tools.ietf.org/html/rfc6125#section-6.4.3
30 | """
31 | pats = []
32 | if not dn:
33 | return False
34 |
35 | # Ported from python3-syntax:
36 | # leftmost, *remainder = dn.split(r'.')
37 | parts = dn.split(r".")
38 | leftmost = parts[0]
39 | remainder = parts[1:]
40 |
41 | wildcards = leftmost.count("*")
42 | if wildcards > max_wildcards:
43 | # Issue #17980: avoid denials of service by refusing more
44 | # than one wildcard per fragment. A survey of established
45 | # policy among SSL implementations showed it to be a
46 | # reasonable choice.
47 | raise CertificateError(
48 | "too many wildcards in certificate DNS name: " + repr(dn)
49 | )
50 |
51 | # speed up common case w/o wildcards
52 | if not wildcards:
53 | return bool(dn.lower() == hostname.lower())
54 |
55 | # RFC 6125, section 6.4.3, subitem 1.
56 | # The client SHOULD NOT attempt to match a presented identifier in which
57 | # the wildcard character comprises a label other than the left-most label.
58 | if leftmost == "*":
59 | # When '*' is a fragment by itself, it matches a non-empty dotless
60 | # fragment.
61 | pats.append("[^.]+")
62 | elif leftmost.startswith("xn--") or hostname.startswith("xn--"):
63 | # RFC 6125, section 6.4.3, subitem 3.
64 | # The client SHOULD NOT attempt to match a presented identifier
65 | # where the wildcard character is embedded within an A-label or
66 | # U-label of an internationalized domain name.
67 | pats.append(re.escape(leftmost))
68 | else:
69 | # Otherwise, '*' matches any dotless string, e.g. www*
70 | pats.append(re.escape(leftmost).replace(r"\*", "[^.]*"))
71 |
72 | # add the remaining fragments, ignore any wildcards
73 | for frag in remainder:
74 | pats.append(re.escape(frag))
75 |
76 | pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE)
77 | return pat.match(hostname)
78 |
79 |
80 | def _ipaddress_match(ipname: str, host_ip: IPv4Address | IPv6Address) -> bool:
81 | """Exact matching of IP addresses.
82 |
83 | RFC 9110 section 4.3.5: "A reference identity of IP-ID contains the decoded
84 | bytes of the IP address. An IP version 4 address is 4 octets, and an IP
85 | version 6 address is 16 octets. [...] A reference identity of type IP-ID
86 | matches if the address is identical to an iPAddress value of the
87 | subjectAltName extension of the certificate."
88 | """
89 | # OpenSSL may add a trailing newline to a subjectAltName's IP address
90 | # Divergence from upstream: ipaddress can't handle byte str
91 | ip = ipaddress.ip_address(ipname.rstrip())
92 | return bool(ip.packed == host_ip.packed)
93 |
94 |
95 | def match_hostname(
96 | cert: _TYPE_PEER_CERT_RET_DICT | None,
97 | hostname: str,
98 | hostname_checks_common_name: bool = False,
99 | ) -> None:
100 | """Verify that *cert* (in decoded format as returned by
101 | SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
102 | rules are followed, but IP addresses are not accepted for *hostname*.
103 |
104 | CertificateError is raised on failure. On success, the function
105 | returns nothing.
106 | """
107 | if not cert:
108 | raise ValueError(
109 | "empty or no certificate, match_hostname needs a "
110 | "SSL socket or SSL context with either "
111 | "CERT_OPTIONAL or CERT_REQUIRED"
112 | )
113 | try:
114 | # Divergence from upstream: ipaddress can't handle byte str
115 | #
116 | # The ipaddress module shipped with Python < 3.9 does not support
117 | # scoped IPv6 addresses so we unconditionally strip the Zone IDs for
118 | # now. Once we drop support for Python 3.9 we can remove this branch.
119 | if "%" in hostname:
120 | host_ip = ipaddress.ip_address(hostname[: hostname.rfind("%")])
121 | else:
122 | host_ip = ipaddress.ip_address(hostname)
123 |
124 | except ValueError:
125 | # Not an IP address (common case)
126 | host_ip = None
127 | dnsnames = []
128 | san: tuple[tuple[str, str], ...] = cert.get("subjectAltName", ())
129 | key: str
130 | value: str
131 | for key, value in san:
132 | if key == "DNS":
133 | if host_ip is None and _dnsname_match(value, hostname):
134 | return
135 | dnsnames.append(value)
136 | elif key == "IP Address":
137 | if host_ip is not None and _ipaddress_match(value, host_ip):
138 | return
139 | dnsnames.append(value)
140 |
141 | # We only check 'commonName' if it's enabled and we're not verifying
142 | # an IP address. IP addresses aren't valid within 'commonName'.
143 | if hostname_checks_common_name and host_ip is None and not dnsnames:
144 | for sub in cert.get("subject", ()):
145 | for key, value in sub:
146 | if key == "commonName":
147 | if _dnsname_match(value, hostname):
148 | return
149 | dnsnames.append(value)
150 |
151 | if len(dnsnames) > 1:
152 | raise CertificateError(
153 | "hostname %r "
154 | "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames)))
155 | )
156 | elif len(dnsnames) == 1:
157 | raise CertificateError(f"hostname {hostname!r} doesn't match {dnsnames[0]!r}")
158 | else:
159 | raise CertificateError("no appropriate subjectAltName fields were found")
160 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/lxml/includes/libxml/relaxng.h:
--------------------------------------------------------------------------------
```
1 | /*
2 | * Summary: implementation of the Relax-NG validation
3 | * Description: implementation of the Relax-NG validation
4 | *
5 | * Copy: See Copyright for the status of this software.
6 | *
7 | * Author: Daniel Veillard
8 | */
9 |
10 | #ifndef __XML_RELAX_NG__
11 | #define __XML_RELAX_NG__
12 |
13 | #include <libxml/xmlversion.h>
14 | #include <libxml/xmlerror.h>
15 | #include <libxml/xmlstring.h>
16 | #include <libxml/tree.h>
17 |
18 | #ifdef LIBXML_SCHEMAS_ENABLED
19 |
20 | #ifdef __cplusplus
21 | extern "C" {
22 | #endif
23 |
24 | typedef struct _xmlRelaxNG xmlRelaxNG;
25 | typedef xmlRelaxNG *xmlRelaxNGPtr;
26 |
27 |
28 | /**
29 | * xmlRelaxNGValidityErrorFunc:
30 | * @ctx: the validation context
31 | * @msg: the message
32 | * @...: extra arguments
33 | *
34 | * Signature of an error callback from a Relax-NG validation
35 | */
36 | typedef void (*xmlRelaxNGValidityErrorFunc) (void *ctx,
37 | const char *msg,
38 | ...) LIBXML_ATTR_FORMAT(2,3);
39 |
40 | /**
41 | * xmlRelaxNGValidityWarningFunc:
42 | * @ctx: the validation context
43 | * @msg: the message
44 | * @...: extra arguments
45 | *
46 | * Signature of a warning callback from a Relax-NG validation
47 | */
48 | typedef void (*xmlRelaxNGValidityWarningFunc) (void *ctx,
49 | const char *msg,
50 | ...) LIBXML_ATTR_FORMAT(2,3);
51 |
52 | /**
53 | * A schemas validation context
54 | */
55 | typedef struct _xmlRelaxNGParserCtxt xmlRelaxNGParserCtxt;
56 | typedef xmlRelaxNGParserCtxt *xmlRelaxNGParserCtxtPtr;
57 |
58 | typedef struct _xmlRelaxNGValidCtxt xmlRelaxNGValidCtxt;
59 | typedef xmlRelaxNGValidCtxt *xmlRelaxNGValidCtxtPtr;
60 |
61 | /*
62 | * xmlRelaxNGValidErr:
63 | *
64 | * List of possible Relax NG validation errors
65 | */
66 | typedef enum {
67 | XML_RELAXNG_OK = 0,
68 | XML_RELAXNG_ERR_MEMORY,
69 | XML_RELAXNG_ERR_TYPE,
70 | XML_RELAXNG_ERR_TYPEVAL,
71 | XML_RELAXNG_ERR_DUPID,
72 | XML_RELAXNG_ERR_TYPECMP,
73 | XML_RELAXNG_ERR_NOSTATE,
74 | XML_RELAXNG_ERR_NODEFINE,
75 | XML_RELAXNG_ERR_LISTEXTRA,
76 | XML_RELAXNG_ERR_LISTEMPTY,
77 | XML_RELAXNG_ERR_INTERNODATA,
78 | XML_RELAXNG_ERR_INTERSEQ,
79 | XML_RELAXNG_ERR_INTEREXTRA,
80 | XML_RELAXNG_ERR_ELEMNAME,
81 | XML_RELAXNG_ERR_ATTRNAME,
82 | XML_RELAXNG_ERR_ELEMNONS,
83 | XML_RELAXNG_ERR_ATTRNONS,
84 | XML_RELAXNG_ERR_ELEMWRONGNS,
85 | XML_RELAXNG_ERR_ATTRWRONGNS,
86 | XML_RELAXNG_ERR_ELEMEXTRANS,
87 | XML_RELAXNG_ERR_ATTREXTRANS,
88 | XML_RELAXNG_ERR_ELEMNOTEMPTY,
89 | XML_RELAXNG_ERR_NOELEM,
90 | XML_RELAXNG_ERR_NOTELEM,
91 | XML_RELAXNG_ERR_ATTRVALID,
92 | XML_RELAXNG_ERR_CONTENTVALID,
93 | XML_RELAXNG_ERR_EXTRACONTENT,
94 | XML_RELAXNG_ERR_INVALIDATTR,
95 | XML_RELAXNG_ERR_DATAELEM,
96 | XML_RELAXNG_ERR_VALELEM,
97 | XML_RELAXNG_ERR_LISTELEM,
98 | XML_RELAXNG_ERR_DATATYPE,
99 | XML_RELAXNG_ERR_VALUE,
100 | XML_RELAXNG_ERR_LIST,
101 | XML_RELAXNG_ERR_NOGRAMMAR,
102 | XML_RELAXNG_ERR_EXTRADATA,
103 | XML_RELAXNG_ERR_LACKDATA,
104 | XML_RELAXNG_ERR_INTERNAL,
105 | XML_RELAXNG_ERR_ELEMWRONG,
106 | XML_RELAXNG_ERR_TEXTWRONG
107 | } xmlRelaxNGValidErr;
108 |
109 | /*
110 | * xmlRelaxNGParserFlags:
111 | *
112 | * List of possible Relax NG Parser flags
113 | */
114 | typedef enum {
115 | XML_RELAXNGP_NONE = 0,
116 | XML_RELAXNGP_FREE_DOC = 1,
117 | XML_RELAXNGP_CRNG = 2
118 | } xmlRelaxNGParserFlag;
119 |
120 | XMLPUBFUN int
121 | xmlRelaxNGInitTypes (void);
122 | XML_DEPRECATED
123 | XMLPUBFUN void
124 | xmlRelaxNGCleanupTypes (void);
125 |
126 | /*
127 | * Interfaces for parsing.
128 | */
129 | XMLPUBFUN xmlRelaxNGParserCtxtPtr
130 | xmlRelaxNGNewParserCtxt (const char *URL);
131 | XMLPUBFUN xmlRelaxNGParserCtxtPtr
132 | xmlRelaxNGNewMemParserCtxt (const char *buffer,
133 | int size);
134 | XMLPUBFUN xmlRelaxNGParserCtxtPtr
135 | xmlRelaxNGNewDocParserCtxt (xmlDocPtr doc);
136 |
137 | XMLPUBFUN int
138 | xmlRelaxParserSetFlag (xmlRelaxNGParserCtxtPtr ctxt,
139 | int flag);
140 |
141 | XMLPUBFUN void
142 | xmlRelaxNGFreeParserCtxt (xmlRelaxNGParserCtxtPtr ctxt);
143 | XMLPUBFUN void
144 | xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
145 | xmlRelaxNGValidityErrorFunc err,
146 | xmlRelaxNGValidityWarningFunc warn,
147 | void *ctx);
148 | XMLPUBFUN int
149 | xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
150 | xmlRelaxNGValidityErrorFunc *err,
151 | xmlRelaxNGValidityWarningFunc *warn,
152 | void **ctx);
153 | XMLPUBFUN void
154 | xmlRelaxNGSetParserStructuredErrors(
155 | xmlRelaxNGParserCtxtPtr ctxt,
156 | xmlStructuredErrorFunc serror,
157 | void *ctx);
158 | XMLPUBFUN xmlRelaxNGPtr
159 | xmlRelaxNGParse (xmlRelaxNGParserCtxtPtr ctxt);
160 | XMLPUBFUN void
161 | xmlRelaxNGFree (xmlRelaxNGPtr schema);
162 | #ifdef LIBXML_OUTPUT_ENABLED
163 | XMLPUBFUN void
164 | xmlRelaxNGDump (FILE *output,
165 | xmlRelaxNGPtr schema);
166 | XMLPUBFUN void
167 | xmlRelaxNGDumpTree (FILE * output,
168 | xmlRelaxNGPtr schema);
169 | #endif /* LIBXML_OUTPUT_ENABLED */
170 | /*
171 | * Interfaces for validating
172 | */
173 | XMLPUBFUN void
174 | xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
175 | xmlRelaxNGValidityErrorFunc err,
176 | xmlRelaxNGValidityWarningFunc warn,
177 | void *ctx);
178 | XMLPUBFUN int
179 | xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
180 | xmlRelaxNGValidityErrorFunc *err,
181 | xmlRelaxNGValidityWarningFunc *warn,
182 | void **ctx);
183 | XMLPUBFUN void
184 | xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt,
185 | xmlStructuredErrorFunc serror, void *ctx);
186 | XMLPUBFUN xmlRelaxNGValidCtxtPtr
187 | xmlRelaxNGNewValidCtxt (xmlRelaxNGPtr schema);
188 | XMLPUBFUN void
189 | xmlRelaxNGFreeValidCtxt (xmlRelaxNGValidCtxtPtr ctxt);
190 | XMLPUBFUN int
191 | xmlRelaxNGValidateDoc (xmlRelaxNGValidCtxtPtr ctxt,
192 | xmlDocPtr doc);
193 | /*
194 | * Interfaces for progressive validation when possible
195 | */
196 | XMLPUBFUN int
197 | xmlRelaxNGValidatePushElement (xmlRelaxNGValidCtxtPtr ctxt,
198 | xmlDocPtr doc,
199 | xmlNodePtr elem);
200 | XMLPUBFUN int
201 | xmlRelaxNGValidatePushCData (xmlRelaxNGValidCtxtPtr ctxt,
202 | const xmlChar *data,
203 | int len);
204 | XMLPUBFUN int
205 | xmlRelaxNGValidatePopElement (xmlRelaxNGValidCtxtPtr ctxt,
206 | xmlDocPtr doc,
207 | xmlNodePtr elem);
208 | XMLPUBFUN int
209 | xmlRelaxNGValidateFullElement (xmlRelaxNGValidCtxtPtr ctxt,
210 | xmlDocPtr doc,
211 | xmlNodePtr elem);
212 |
213 | #ifdef __cplusplus
214 | }
215 | #endif
216 |
217 | #endif /* LIBXML_SCHEMAS_ENABLED */
218 |
219 | #endif /* __XML_RELAX_NG__ */
220 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/flask/wrappers.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import typing as t
4 |
5 | from werkzeug.exceptions import BadRequest
6 | from werkzeug.exceptions import HTTPException
7 | from werkzeug.wrappers import Request as RequestBase
8 | from werkzeug.wrappers import Response as ResponseBase
9 |
10 | from . import json
11 | from .globals import current_app
12 | from .helpers import _split_blueprint_path
13 |
14 | if t.TYPE_CHECKING: # pragma: no cover
15 | from werkzeug.routing import Rule
16 |
17 |
18 | class Request(RequestBase):
19 | """The request object used by default in Flask. Remembers the
20 | matched endpoint and view arguments.
21 |
22 | It is what ends up as :class:`~flask.request`. If you want to replace
23 | the request object used you can subclass this and set
24 | :attr:`~flask.Flask.request_class` to your subclass.
25 |
26 | The request object is a :class:`~werkzeug.wrappers.Request` subclass and
27 | provides all of the attributes Werkzeug defines plus a few Flask
28 | specific ones.
29 | """
30 |
31 | json_module: t.Any = json
32 |
33 | #: The internal URL rule that matched the request. This can be
34 | #: useful to inspect which methods are allowed for the URL from
35 | #: a before/after handler (``request.url_rule.methods``) etc.
36 | #: Though if the request's method was invalid for the URL rule,
37 | #: the valid list is available in ``routing_exception.valid_methods``
38 | #: instead (an attribute of the Werkzeug exception
39 | #: :exc:`~werkzeug.exceptions.MethodNotAllowed`)
40 | #: because the request was never internally bound.
41 | #:
42 | #: .. versionadded:: 0.6
43 | url_rule: Rule | None = None
44 |
45 | #: A dict of view arguments that matched the request. If an exception
46 | #: happened when matching, this will be ``None``.
47 | view_args: dict[str, t.Any] | None = None
48 |
49 | #: If matching the URL failed, this is the exception that will be
50 | #: raised / was raised as part of the request handling. This is
51 | #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
52 | #: something similar.
53 | routing_exception: HTTPException | None = None
54 |
55 | @property
56 | def max_content_length(self) -> int | None: # type: ignore[override]
57 | """Read-only view of the ``MAX_CONTENT_LENGTH`` config key."""
58 | if current_app:
59 | return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return]
60 | else:
61 | return None
62 |
63 | @property
64 | def endpoint(self) -> str | None:
65 | """The endpoint that matched the request URL.
66 |
67 | This will be ``None`` if matching failed or has not been
68 | performed yet.
69 |
70 | This in combination with :attr:`view_args` can be used to
71 | reconstruct the same URL or a modified URL.
72 | """
73 | if self.url_rule is not None:
74 | return self.url_rule.endpoint
75 |
76 | return None
77 |
78 | @property
79 | def blueprint(self) -> str | None:
80 | """The registered name of the current blueprint.
81 |
82 | This will be ``None`` if the endpoint is not part of a
83 | blueprint, or if URL matching failed or has not been performed
84 | yet.
85 |
86 | This does not necessarily match the name the blueprint was
87 | created with. It may have been nested, or registered with a
88 | different name.
89 | """
90 | endpoint = self.endpoint
91 |
92 | if endpoint is not None and "." in endpoint:
93 | return endpoint.rpartition(".")[0]
94 |
95 | return None
96 |
97 | @property
98 | def blueprints(self) -> list[str]:
99 | """The registered names of the current blueprint upwards through
100 | parent blueprints.
101 |
102 | This will be an empty list if there is no current blueprint, or
103 | if URL matching failed.
104 |
105 | .. versionadded:: 2.0.1
106 | """
107 | name = self.blueprint
108 |
109 | if name is None:
110 | return []
111 |
112 | return _split_blueprint_path(name)
113 |
114 | def _load_form_data(self) -> None:
115 | super()._load_form_data()
116 |
117 | # In debug mode we're replacing the files multidict with an ad-hoc
118 | # subclass that raises a different error for key errors.
119 | if (
120 | current_app
121 | and current_app.debug
122 | and self.mimetype != "multipart/form-data"
123 | and not self.files
124 | ):
125 | from .debughelpers import attach_enctype_error_multidict
126 |
127 | attach_enctype_error_multidict(self)
128 |
129 | def on_json_loading_failed(self, e: ValueError | None) -> t.Any:
130 | try:
131 | return super().on_json_loading_failed(e)
132 | except BadRequest as e:
133 | if current_app and current_app.debug:
134 | raise
135 |
136 | raise BadRequest() from e
137 |
138 |
139 | class Response(ResponseBase):
140 | """The response object that is used by default in Flask. Works like the
141 | response object from Werkzeug but is set to have an HTML mimetype by
142 | default. Quite often you don't have to create this object yourself because
143 | :meth:`~flask.Flask.make_response` will take care of that for you.
144 |
145 | If you want to replace the response object used you can subclass this and
146 | set :attr:`~flask.Flask.response_class` to your subclass.
147 |
148 | .. versionchanged:: 1.0
149 | JSON support is added to the response, like the request. This is useful
150 | when testing to get the test client response data as JSON.
151 |
152 | .. versionchanged:: 1.0
153 |
154 | Added :attr:`max_cookie_size`.
155 | """
156 |
157 | default_mimetype: str | None = "text/html"
158 |
159 | json_module = json
160 |
161 | autocorrect_location_header = False
162 |
163 | @property
164 | def max_cookie_size(self) -> int: # type: ignore
165 | """Read-only view of the :data:`MAX_COOKIE_SIZE` config key.
166 |
167 | See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in
168 | Werkzeug's docs.
169 | """
170 | if current_app:
171 | return current_app.config["MAX_COOKIE_SIZE"] # type: ignore[no-any-return]
172 |
173 | # return Werkzeug's default when not in an app context
174 | return super().max_cookie_size
175 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/providers.py:
--------------------------------------------------------------------------------
```python
1 | class AbstractProvider(object):
2 | """Delegate class to provide the required interface for the resolver."""
3 |
4 | def identify(self, requirement_or_candidate):
5 | """Given a requirement, return an identifier for it.
6 |
7 | This is used to identify a requirement, e.g. whether two requirements
8 | should have their specifier parts merged.
9 | """
10 | raise NotImplementedError
11 |
12 | def get_preference(
13 | self,
14 | identifier,
15 | resolutions,
16 | candidates,
17 | information,
18 | backtrack_causes,
19 | ):
20 | """Produce a sort key for given requirement based on preference.
21 |
22 | The preference is defined as "I think this requirement should be
23 | resolved first". The lower the return value is, the more preferred
24 | this group of arguments is.
25 |
26 | :param identifier: An identifier as returned by ``identify()``. This
27 | identifies the dependency matches which should be returned.
28 | :param resolutions: Mapping of candidates currently pinned by the
29 | resolver. Each key is an identifier, and the value is a candidate.
30 | The candidate may conflict with requirements from ``information``.
31 | :param candidates: Mapping of each dependency's possible candidates.
32 | Each value is an iterator of candidates.
33 | :param information: Mapping of requirement information of each package.
34 | Each value is an iterator of *requirement information*.
35 | :param backtrack_causes: Sequence of requirement information that were
36 | the requirements that caused the resolver to most recently backtrack.
37 |
38 | A *requirement information* instance is a named tuple with two members:
39 |
40 | * ``requirement`` specifies a requirement contributing to the current
41 | list of candidates.
42 | * ``parent`` specifies the candidate that provides (depended on) the
43 | requirement, or ``None`` to indicate a root requirement.
44 |
45 | The preference could depend on various issues, including (not
46 | necessarily in this order):
47 |
48 | * Is this package pinned in the current resolution result?
49 | * How relaxed is the requirement? Stricter ones should probably be
50 | worked on first? (I don't know, actually.)
51 | * How many possibilities are there to satisfy this requirement? Those
52 | with few left should likely be worked on first, I guess?
53 | * Are there any known conflicts for this requirement? We should
54 | probably work on those with the most known conflicts.
55 |
56 | A sortable value should be returned (this will be used as the ``key``
57 | parameter of the built-in sorting function). The smaller the value is,
58 | the more preferred this requirement is (i.e. the sorting function
59 | is called with ``reverse=False``).
60 | """
61 | raise NotImplementedError
62 |
63 | def find_matches(self, identifier, requirements, incompatibilities):
64 | """Find all possible candidates that satisfy the given constraints.
65 |
66 | :param identifier: An identifier as returned by ``identify()``. This
67 | identifies the dependency matches of which should be returned.
68 | :param requirements: A mapping of requirements that all returned
69 | candidates must satisfy. Each key is an identifier, and the value
70 | an iterator of requirements for that dependency.
71 | :param incompatibilities: A mapping of known incompatibilities of
72 | each dependency. Each key is an identifier, and the value an
73 | iterator of incompatibilities known to the resolver. All
74 | incompatibilities *must* be excluded from the return value.
75 |
76 | This should try to get candidates based on the requirements' types.
77 | For VCS, local, and archive requirements, the one-and-only match is
78 | returned, and for a "named" requirement, the index(es) should be
79 | consulted to find concrete candidates for this requirement.
80 |
81 | The return value should produce candidates ordered by preference; the
82 | most preferred candidate should come first. The return type may be one
83 | of the following:
84 |
85 | * A callable that returns an iterator that yields candidates.
86 | * An collection of candidates.
87 | * An iterable of candidates. This will be consumed immediately into a
88 | list of candidates.
89 | """
90 | raise NotImplementedError
91 |
92 | def is_satisfied_by(self, requirement, candidate):
93 | """Whether the given requirement can be satisfied by a candidate.
94 |
95 | The candidate is guaranteed to have been generated from the
96 | requirement.
97 |
98 | A boolean should be returned to indicate whether ``candidate`` is a
99 | viable solution to the requirement.
100 | """
101 | raise NotImplementedError
102 |
103 | def get_dependencies(self, candidate):
104 | """Get dependencies of a candidate.
105 |
106 | This should return a collection of requirements that `candidate`
107 | specifies as its dependencies.
108 | """
109 | raise NotImplementedError
110 |
111 |
112 | class AbstractResolver(object):
113 | """The thing that performs the actual resolution work."""
114 |
115 | base_exception = Exception
116 |
117 | def __init__(self, provider, reporter):
118 | self.provider = provider
119 | self.reporter = reporter
120 |
121 | def resolve(self, requirements, **kwargs):
122 | """Take a collection of constraints, spit out the resolution result.
123 |
124 | This returns a representation of the final resolution state, with one
125 | guarenteed attribute ``mapping`` that contains resolved candidates as
126 | values. The keys are their respective identifiers.
127 |
128 | :param requirements: A collection of constraints.
129 | :param kwargs: Additional keyword arguments that subclasses may accept.
130 |
131 | :raises: ``self.base_exception`` or its subclass.
132 | """
133 | raise NotImplementedError
134 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/operations/check.py:
--------------------------------------------------------------------------------
```python
1 | """Validation of dependencies of packages
2 | """
3 |
4 | import logging
5 | from contextlib import suppress
6 | from email.parser import Parser
7 | from functools import reduce
8 | from typing import (
9 | Callable,
10 | Dict,
11 | FrozenSet,
12 | Generator,
13 | Iterable,
14 | List,
15 | NamedTuple,
16 | Optional,
17 | Set,
18 | Tuple,
19 | )
20 |
21 | from pip._vendor.packaging.requirements import Requirement
22 | from pip._vendor.packaging.tags import Tag, parse_tag
23 | from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
24 | from pip._vendor.packaging.version import Version
25 |
26 | from pip._internal.distributions import make_distribution_for_install_requirement
27 | from pip._internal.metadata import get_default_environment
28 | from pip._internal.metadata.base import BaseDistribution
29 | from pip._internal.req.req_install import InstallRequirement
30 |
31 | logger = logging.getLogger(__name__)
32 |
33 |
34 | class PackageDetails(NamedTuple):
35 | version: Version
36 | dependencies: List[Requirement]
37 |
38 |
39 | # Shorthands
40 | PackageSet = Dict[NormalizedName, PackageDetails]
41 | Missing = Tuple[NormalizedName, Requirement]
42 | Conflicting = Tuple[NormalizedName, Version, Requirement]
43 |
44 | MissingDict = Dict[NormalizedName, List[Missing]]
45 | ConflictingDict = Dict[NormalizedName, List[Conflicting]]
46 | CheckResult = Tuple[MissingDict, ConflictingDict]
47 | ConflictDetails = Tuple[PackageSet, CheckResult]
48 |
49 |
50 | def create_package_set_from_installed() -> Tuple[PackageSet, bool]:
51 | """Converts a list of distributions into a PackageSet."""
52 | package_set = {}
53 | problems = False
54 | env = get_default_environment()
55 | for dist in env.iter_installed_distributions(local_only=False, skip=()):
56 | name = dist.canonical_name
57 | try:
58 | dependencies = list(dist.iter_dependencies())
59 | package_set[name] = PackageDetails(dist.version, dependencies)
60 | except (OSError, ValueError) as e:
61 | # Don't crash on unreadable or broken metadata.
62 | logger.warning("Error parsing dependencies of %s: %s", name, e)
63 | problems = True
64 | return package_set, problems
65 |
66 |
67 | def check_package_set(
68 | package_set: PackageSet, should_ignore: Optional[Callable[[str], bool]] = None
69 | ) -> CheckResult:
70 | """Check if a package set is consistent
71 |
72 | If should_ignore is passed, it should be a callable that takes a
73 | package name and returns a boolean.
74 | """
75 |
76 | missing = {}
77 | conflicting = {}
78 |
79 | for package_name, package_detail in package_set.items():
80 | # Info about dependencies of package_name
81 | missing_deps: Set[Missing] = set()
82 | conflicting_deps: Set[Conflicting] = set()
83 |
84 | if should_ignore and should_ignore(package_name):
85 | continue
86 |
87 | for req in package_detail.dependencies:
88 | name = canonicalize_name(req.name)
89 |
90 | # Check if it's missing
91 | if name not in package_set:
92 | missed = True
93 | if req.marker is not None:
94 | missed = req.marker.evaluate({"extra": ""})
95 | if missed:
96 | missing_deps.add((name, req))
97 | continue
98 |
99 | # Check if there's a conflict
100 | version = package_set[name].version
101 | if not req.specifier.contains(version, prereleases=True):
102 | conflicting_deps.add((name, version, req))
103 |
104 | if missing_deps:
105 | missing[package_name] = sorted(missing_deps, key=str)
106 | if conflicting_deps:
107 | conflicting[package_name] = sorted(conflicting_deps, key=str)
108 |
109 | return missing, conflicting
110 |
111 |
112 | def check_install_conflicts(to_install: List[InstallRequirement]) -> ConflictDetails:
113 | """For checking if the dependency graph would be consistent after \
114 | installing given requirements
115 | """
116 | # Start from the current state
117 | package_set, _ = create_package_set_from_installed()
118 | # Install packages
119 | would_be_installed = _simulate_installation_of(to_install, package_set)
120 |
121 | # Only warn about directly-dependent packages; create a whitelist of them
122 | whitelist = _create_whitelist(would_be_installed, package_set)
123 |
124 | return (
125 | package_set,
126 | check_package_set(
127 | package_set, should_ignore=lambda name: name not in whitelist
128 | ),
129 | )
130 |
131 |
132 | def check_unsupported(
133 | packages: Iterable[BaseDistribution],
134 | supported_tags: Iterable[Tag],
135 | ) -> Generator[BaseDistribution, None, None]:
136 | for p in packages:
137 | with suppress(FileNotFoundError):
138 | wheel_file = p.read_text("WHEEL")
139 | wheel_tags: FrozenSet[Tag] = reduce(
140 | frozenset.union,
141 | map(parse_tag, Parser().parsestr(wheel_file).get_all("Tag", [])),
142 | frozenset(),
143 | )
144 | if wheel_tags.isdisjoint(supported_tags):
145 | yield p
146 |
147 |
148 | def _simulate_installation_of(
149 | to_install: List[InstallRequirement], package_set: PackageSet
150 | ) -> Set[NormalizedName]:
151 | """Computes the version of packages after installing to_install."""
152 | # Keep track of packages that were installed
153 | installed = set()
154 |
155 | # Modify it as installing requirement_set would (assuming no errors)
156 | for inst_req in to_install:
157 | abstract_dist = make_distribution_for_install_requirement(inst_req)
158 | dist = abstract_dist.get_metadata_distribution()
159 | name = dist.canonical_name
160 | package_set[name] = PackageDetails(dist.version, list(dist.iter_dependencies()))
161 |
162 | installed.add(name)
163 |
164 | return installed
165 |
166 |
167 | def _create_whitelist(
168 | would_be_installed: Set[NormalizedName], package_set: PackageSet
169 | ) -> Set[NormalizedName]:
170 | packages_affected = set(would_be_installed)
171 |
172 | for package_name in package_set:
173 | if package_name in packages_affected:
174 | continue
175 |
176 | for req in package_set[package_name].dependencies:
177 | if canonicalize_name(req.name) in packages_affected:
178 | packages_affected.add(package_name)
179 | break
180 |
181 | return packages_affected
182 |
```