This is page 85 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/exceptions.py:
--------------------------------------------------------------------------------
```python
1 | """Exceptions used throughout package.
2 |
3 | This module MUST NOT try to import from anything within `pip._internal` to
4 | operate. This is expected to be importable from any/all files within the
5 | subpackage and, thus, should not depend on them.
6 | """
7 |
8 | import configparser
9 | import contextlib
10 | import locale
11 | import logging
12 | import pathlib
13 | import re
14 | import sys
15 | from itertools import chain, groupby, repeat
16 | from typing import TYPE_CHECKING, Dict, Iterator, List, Literal, Optional, Union
17 |
18 | from pip._vendor.rich.console import Console, ConsoleOptions, RenderResult
19 | from pip._vendor.rich.markup import escape
20 | from pip._vendor.rich.text import Text
21 |
22 | if TYPE_CHECKING:
23 | from hashlib import _Hash
24 |
25 | from pip._vendor.requests.models import Request, Response
26 |
27 | from pip._internal.metadata import BaseDistribution
28 | from pip._internal.req.req_install import InstallRequirement
29 |
30 | logger = logging.getLogger(__name__)
31 |
32 |
33 | #
34 | # Scaffolding
35 | #
36 | def _is_kebab_case(s: str) -> bool:
37 | return re.match(r"^[a-z]+(-[a-z]+)*$", s) is not None
38 |
39 |
40 | def _prefix_with_indent(
41 | s: Union[Text, str],
42 | console: Console,
43 | *,
44 | prefix: str,
45 | indent: str,
46 | ) -> Text:
47 | if isinstance(s, Text):
48 | text = s
49 | else:
50 | text = console.render_str(s)
51 |
52 | return console.render_str(prefix, overflow="ignore") + console.render_str(
53 | f"\n{indent}", overflow="ignore"
54 | ).join(text.split(allow_blank=True))
55 |
56 |
57 | class PipError(Exception):
58 | """The base pip error."""
59 |
60 |
61 | class DiagnosticPipError(PipError):
62 | """An error, that presents diagnostic information to the user.
63 |
64 | This contains a bunch of logic, to enable pretty presentation of our error
65 | messages. Each error gets a unique reference. Each error can also include
66 | additional context, a hint and/or a note -- which are presented with the
67 | main error message in a consistent style.
68 |
69 | This is adapted from the error output styling in `sphinx-theme-builder`.
70 | """
71 |
72 | reference: str
73 |
74 | def __init__(
75 | self,
76 | *,
77 | kind: 'Literal["error", "warning"]' = "error",
78 | reference: Optional[str] = None,
79 | message: Union[str, Text],
80 | context: Optional[Union[str, Text]],
81 | hint_stmt: Optional[Union[str, Text]],
82 | note_stmt: Optional[Union[str, Text]] = None,
83 | link: Optional[str] = None,
84 | ) -> None:
85 | # Ensure a proper reference is provided.
86 | if reference is None:
87 | assert hasattr(self, "reference"), "error reference not provided!"
88 | reference = self.reference
89 | assert _is_kebab_case(reference), "error reference must be kebab-case!"
90 |
91 | self.kind = kind
92 | self.reference = reference
93 |
94 | self.message = message
95 | self.context = context
96 |
97 | self.note_stmt = note_stmt
98 | self.hint_stmt = hint_stmt
99 |
100 | self.link = link
101 |
102 | super().__init__(f"<{self.__class__.__name__}: {self.reference}>")
103 |
104 | def __repr__(self) -> str:
105 | return (
106 | f"<{self.__class__.__name__}("
107 | f"reference={self.reference!r}, "
108 | f"message={self.message!r}, "
109 | f"context={self.context!r}, "
110 | f"note_stmt={self.note_stmt!r}, "
111 | f"hint_stmt={self.hint_stmt!r}"
112 | ")>"
113 | )
114 |
115 | def __rich_console__(
116 | self,
117 | console: Console,
118 | options: ConsoleOptions,
119 | ) -> RenderResult:
120 | colour = "red" if self.kind == "error" else "yellow"
121 |
122 | yield f"[{colour} bold]{self.kind}[/]: [bold]{self.reference}[/]"
123 | yield ""
124 |
125 | if not options.ascii_only:
126 | # Present the main message, with relevant context indented.
127 | if self.context is not None:
128 | yield _prefix_with_indent(
129 | self.message,
130 | console,
131 | prefix=f"[{colour}]×[/] ",
132 | indent=f"[{colour}]│[/] ",
133 | )
134 | yield _prefix_with_indent(
135 | self.context,
136 | console,
137 | prefix=f"[{colour}]╰─>[/] ",
138 | indent=f"[{colour}] [/] ",
139 | )
140 | else:
141 | yield _prefix_with_indent(
142 | self.message,
143 | console,
144 | prefix="[red]×[/] ",
145 | indent=" ",
146 | )
147 | else:
148 | yield self.message
149 | if self.context is not None:
150 | yield ""
151 | yield self.context
152 |
153 | if self.note_stmt is not None or self.hint_stmt is not None:
154 | yield ""
155 |
156 | if self.note_stmt is not None:
157 | yield _prefix_with_indent(
158 | self.note_stmt,
159 | console,
160 | prefix="[magenta bold]note[/]: ",
161 | indent=" ",
162 | )
163 | if self.hint_stmt is not None:
164 | yield _prefix_with_indent(
165 | self.hint_stmt,
166 | console,
167 | prefix="[cyan bold]hint[/]: ",
168 | indent=" ",
169 | )
170 |
171 | if self.link is not None:
172 | yield ""
173 | yield f"Link: {self.link}"
174 |
175 |
176 | #
177 | # Actual Errors
178 | #
179 | class ConfigurationError(PipError):
180 | """General exception in configuration"""
181 |
182 |
183 | class InstallationError(PipError):
184 | """General exception during installation"""
185 |
186 |
187 | class MissingPyProjectBuildRequires(DiagnosticPipError):
188 | """Raised when pyproject.toml has `build-system`, but no `build-system.requires`."""
189 |
190 | reference = "missing-pyproject-build-system-requires"
191 |
192 | def __init__(self, *, package: str) -> None:
193 | super().__init__(
194 | message=f"Can not process {escape(package)}",
195 | context=Text(
196 | "This package has an invalid pyproject.toml file.\n"
197 | "The [build-system] table is missing the mandatory `requires` key."
198 | ),
199 | note_stmt="This is an issue with the package mentioned above, not pip.",
200 | hint_stmt=Text("See PEP 518 for the detailed specification."),
201 | )
202 |
203 |
204 | class InvalidPyProjectBuildRequires(DiagnosticPipError):
205 | """Raised when pyproject.toml an invalid `build-system.requires`."""
206 |
207 | reference = "invalid-pyproject-build-system-requires"
208 |
209 | def __init__(self, *, package: str, reason: str) -> None:
210 | super().__init__(
211 | message=f"Can not process {escape(package)}",
212 | context=Text(
213 | "This package has an invalid `build-system.requires` key in "
214 | f"pyproject.toml.\n{reason}"
215 | ),
216 | note_stmt="This is an issue with the package mentioned above, not pip.",
217 | hint_stmt=Text("See PEP 518 for the detailed specification."),
218 | )
219 |
220 |
221 | class NoneMetadataError(PipError):
222 | """Raised when accessing a Distribution's "METADATA" or "PKG-INFO".
223 |
224 | This signifies an inconsistency, when the Distribution claims to have
225 | the metadata file (if not, raise ``FileNotFoundError`` instead), but is
226 | not actually able to produce its content. This may be due to permission
227 | errors.
228 | """
229 |
230 | def __init__(
231 | self,
232 | dist: "BaseDistribution",
233 | metadata_name: str,
234 | ) -> None:
235 | """
236 | :param dist: A Distribution object.
237 | :param metadata_name: The name of the metadata being accessed
238 | (can be "METADATA" or "PKG-INFO").
239 | """
240 | self.dist = dist
241 | self.metadata_name = metadata_name
242 |
243 | def __str__(self) -> str:
244 | # Use `dist` in the error message because its stringification
245 | # includes more information, like the version and location.
246 | return f"None {self.metadata_name} metadata found for distribution: {self.dist}"
247 |
248 |
249 | class UserInstallationInvalid(InstallationError):
250 | """A --user install is requested on an environment without user site."""
251 |
252 | def __str__(self) -> str:
253 | return "User base directory is not specified"
254 |
255 |
256 | class InvalidSchemeCombination(InstallationError):
257 | def __str__(self) -> str:
258 | before = ", ".join(str(a) for a in self.args[:-1])
259 | return f"Cannot set {before} and {self.args[-1]} together"
260 |
261 |
262 | class DistributionNotFound(InstallationError):
263 | """Raised when a distribution cannot be found to satisfy a requirement"""
264 |
265 |
266 | class RequirementsFileParseError(InstallationError):
267 | """Raised when a general error occurs parsing a requirements file line."""
268 |
269 |
270 | class BestVersionAlreadyInstalled(PipError):
271 | """Raised when the most up-to-date version of a package is already
272 | installed."""
273 |
274 |
275 | class BadCommand(PipError):
276 | """Raised when virtualenv or a command is not found"""
277 |
278 |
279 | class CommandError(PipError):
280 | """Raised when there is an error in command-line arguments"""
281 |
282 |
283 | class PreviousBuildDirError(PipError):
284 | """Raised when there's a previous conflicting build directory"""
285 |
286 |
287 | class NetworkConnectionError(PipError):
288 | """HTTP connection error"""
289 |
290 | def __init__(
291 | self,
292 | error_msg: str,
293 | response: Optional["Response"] = None,
294 | request: Optional["Request"] = None,
295 | ) -> None:
296 | """
297 | Initialize NetworkConnectionError with `request` and `response`
298 | objects.
299 | """
300 | self.response = response
301 | self.request = request
302 | self.error_msg = error_msg
303 | if (
304 | self.response is not None
305 | and not self.request
306 | and hasattr(response, "request")
307 | ):
308 | self.request = self.response.request
309 | super().__init__(error_msg, response, request)
310 |
311 | def __str__(self) -> str:
312 | return str(self.error_msg)
313 |
314 |
315 | class InvalidWheelFilename(InstallationError):
316 | """Invalid wheel filename."""
317 |
318 |
319 | class UnsupportedWheel(InstallationError):
320 | """Unsupported wheel."""
321 |
322 |
323 | class InvalidWheel(InstallationError):
324 | """Invalid (e.g. corrupt) wheel."""
325 |
326 | def __init__(self, location: str, name: str):
327 | self.location = location
328 | self.name = name
329 |
330 | def __str__(self) -> str:
331 | return f"Wheel '{self.name}' located at {self.location} is invalid."
332 |
333 |
334 | class MetadataInconsistent(InstallationError):
335 | """Built metadata contains inconsistent information.
336 |
337 | This is raised when the metadata contains values (e.g. name and version)
338 | that do not match the information previously obtained from sdist filename,
339 | user-supplied ``#egg=`` value, or an install requirement name.
340 | """
341 |
342 | def __init__(
343 | self, ireq: "InstallRequirement", field: str, f_val: str, m_val: str
344 | ) -> None:
345 | self.ireq = ireq
346 | self.field = field
347 | self.f_val = f_val
348 | self.m_val = m_val
349 |
350 | def __str__(self) -> str:
351 | return (
352 | f"Requested {self.ireq} has inconsistent {self.field}: "
353 | f"expected {self.f_val!r}, but metadata has {self.m_val!r}"
354 | )
355 |
356 |
357 | class MetadataInvalid(InstallationError):
358 | """Metadata is invalid."""
359 |
360 | def __init__(self, ireq: "InstallRequirement", error: str) -> None:
361 | self.ireq = ireq
362 | self.error = error
363 |
364 | def __str__(self) -> str:
365 | return f"Requested {self.ireq} has invalid metadata: {self.error}"
366 |
367 |
368 | class InstallationSubprocessError(DiagnosticPipError, InstallationError):
369 | """A subprocess call failed."""
370 |
371 | reference = "subprocess-exited-with-error"
372 |
373 | def __init__(
374 | self,
375 | *,
376 | command_description: str,
377 | exit_code: int,
378 | output_lines: Optional[List[str]],
379 | ) -> None:
380 | if output_lines is None:
381 | output_prompt = Text("See above for output.")
382 | else:
383 | output_prompt = (
384 | Text.from_markup(f"[red][{len(output_lines)} lines of output][/]\n")
385 | + Text("".join(output_lines))
386 | + Text.from_markup(R"[red]\[end of output][/]")
387 | )
388 |
389 | super().__init__(
390 | message=(
391 | f"[green]{escape(command_description)}[/] did not run successfully.\n"
392 | f"exit code: {exit_code}"
393 | ),
394 | context=output_prompt,
395 | hint_stmt=None,
396 | note_stmt=(
397 | "This error originates from a subprocess, and is likely not a "
398 | "problem with pip."
399 | ),
400 | )
401 |
402 | self.command_description = command_description
403 | self.exit_code = exit_code
404 |
405 | def __str__(self) -> str:
406 | return f"{self.command_description} exited with {self.exit_code}"
407 |
408 |
409 | class MetadataGenerationFailed(InstallationSubprocessError, InstallationError):
410 | reference = "metadata-generation-failed"
411 |
412 | def __init__(
413 | self,
414 | *,
415 | package_details: str,
416 | ) -> None:
417 | super(InstallationSubprocessError, self).__init__(
418 | message="Encountered error while generating package metadata.",
419 | context=escape(package_details),
420 | hint_stmt="See above for details.",
421 | note_stmt="This is an issue with the package mentioned above, not pip.",
422 | )
423 |
424 | def __str__(self) -> str:
425 | return "metadata generation failed"
426 |
427 |
428 | class HashErrors(InstallationError):
429 | """Multiple HashError instances rolled into one for reporting"""
430 |
431 | def __init__(self) -> None:
432 | self.errors: List["HashError"] = []
433 |
434 | def append(self, error: "HashError") -> None:
435 | self.errors.append(error)
436 |
437 | def __str__(self) -> str:
438 | lines = []
439 | self.errors.sort(key=lambda e: e.order)
440 | for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__):
441 | lines.append(cls.head)
442 | lines.extend(e.body() for e in errors_of_cls)
443 | if lines:
444 | return "\n".join(lines)
445 | return ""
446 |
447 | def __bool__(self) -> bool:
448 | return bool(self.errors)
449 |
450 |
451 | class HashError(InstallationError):
452 | """
453 | A failure to verify a package against known-good hashes
454 |
455 | :cvar order: An int sorting hash exception classes by difficulty of
456 | recovery (lower being harder), so the user doesn't bother fretting
457 | about unpinned packages when he has deeper issues, like VCS
458 | dependencies, to deal with. Also keeps error reports in a
459 | deterministic order.
460 | :cvar head: A section heading for display above potentially many
461 | exceptions of this kind
462 | :ivar req: The InstallRequirement that triggered this error. This is
463 | pasted on after the exception is instantiated, because it's not
464 | typically available earlier.
465 |
466 | """
467 |
468 | req: Optional["InstallRequirement"] = None
469 | head = ""
470 | order: int = -1
471 |
472 | def body(self) -> str:
473 | """Return a summary of me for display under the heading.
474 |
475 | This default implementation simply prints a description of the
476 | triggering requirement.
477 |
478 | :param req: The InstallRequirement that provoked this error, with
479 | its link already populated by the resolver's _populate_link().
480 |
481 | """
482 | return f" {self._requirement_name()}"
483 |
484 | def __str__(self) -> str:
485 | return f"{self.head}\n{self.body()}"
486 |
487 | def _requirement_name(self) -> str:
488 | """Return a description of the requirement that triggered me.
489 |
490 | This default implementation returns long description of the req, with
491 | line numbers
492 |
493 | """
494 | return str(self.req) if self.req else "unknown package"
495 |
496 |
497 | class VcsHashUnsupported(HashError):
498 | """A hash was provided for a version-control-system-based requirement, but
499 | we don't have a method for hashing those."""
500 |
501 | order = 0
502 | head = (
503 | "Can't verify hashes for these requirements because we don't "
504 | "have a way to hash version control repositories:"
505 | )
506 |
507 |
508 | class DirectoryUrlHashUnsupported(HashError):
509 | """A hash was provided for a version-control-system-based requirement, but
510 | we don't have a method for hashing those."""
511 |
512 | order = 1
513 | head = (
514 | "Can't verify hashes for these file:// requirements because they "
515 | "point to directories:"
516 | )
517 |
518 |
519 | class HashMissing(HashError):
520 | """A hash was needed for a requirement but is absent."""
521 |
522 | order = 2
523 | head = (
524 | "Hashes are required in --require-hashes mode, but they are "
525 | "missing from some requirements. Here is a list of those "
526 | "requirements along with the hashes their downloaded archives "
527 | "actually had. Add lines like these to your requirements files to "
528 | "prevent tampering. (If you did not enable --require-hashes "
529 | "manually, note that it turns on automatically when any package "
530 | "has a hash.)"
531 | )
532 |
533 | def __init__(self, gotten_hash: str) -> None:
534 | """
535 | :param gotten_hash: The hash of the (possibly malicious) archive we
536 | just downloaded
537 | """
538 | self.gotten_hash = gotten_hash
539 |
540 | def body(self) -> str:
541 | # Dodge circular import.
542 | from pip._internal.utils.hashes import FAVORITE_HASH
543 |
544 | package = None
545 | if self.req:
546 | # In the case of URL-based requirements, display the original URL
547 | # seen in the requirements file rather than the package name,
548 | # so the output can be directly copied into the requirements file.
549 | package = (
550 | self.req.original_link
551 | if self.req.is_direct
552 | # In case someone feeds something downright stupid
553 | # to InstallRequirement's constructor.
554 | else getattr(self.req, "req", None)
555 | )
556 | return " {} --hash={}:{}".format(
557 | package or "unknown package", FAVORITE_HASH, self.gotten_hash
558 | )
559 |
560 |
561 | class HashUnpinned(HashError):
562 | """A requirement had a hash specified but was not pinned to a specific
563 | version."""
564 |
565 | order = 3
566 | head = (
567 | "In --require-hashes mode, all requirements must have their "
568 | "versions pinned with ==. These do not:"
569 | )
570 |
571 |
572 | class HashMismatch(HashError):
573 | """
574 | Distribution file hash values don't match.
575 |
576 | :ivar package_name: The name of the package that triggered the hash
577 | mismatch. Feel free to write to this after the exception is raise to
578 | improve its error message.
579 |
580 | """
581 |
582 | order = 4
583 | head = (
584 | "THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS "
585 | "FILE. If you have updated the package versions, please update "
586 | "the hashes. Otherwise, examine the package contents carefully; "
587 | "someone may have tampered with them."
588 | )
589 |
590 | def __init__(self, allowed: Dict[str, List[str]], gots: Dict[str, "_Hash"]) -> None:
591 | """
592 | :param allowed: A dict of algorithm names pointing to lists of allowed
593 | hex digests
594 | :param gots: A dict of algorithm names pointing to hashes we
595 | actually got from the files under suspicion
596 | """
597 | self.allowed = allowed
598 | self.gots = gots
599 |
600 | def body(self) -> str:
601 | return f" {self._requirement_name()}:\n{self._hash_comparison()}"
602 |
603 | def _hash_comparison(self) -> str:
604 | """
605 | Return a comparison of actual and expected hash values.
606 |
607 | Example::
608 |
609 | Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde
610 | or 123451234512345123451234512345123451234512345
611 | Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef
612 |
613 | """
614 |
615 | def hash_then_or(hash_name: str) -> "chain[str]":
616 | # For now, all the decent hashes have 6-char names, so we can get
617 | # away with hard-coding space literals.
618 | return chain([hash_name], repeat(" or"))
619 |
620 | lines: List[str] = []
621 | for hash_name, expecteds in self.allowed.items():
622 | prefix = hash_then_or(hash_name)
623 | lines.extend((f" Expected {next(prefix)} {e}") for e in expecteds)
624 | lines.append(
625 | f" Got {self.gots[hash_name].hexdigest()}\n"
626 | )
627 | return "\n".join(lines)
628 |
629 |
630 | class UnsupportedPythonVersion(InstallationError):
631 | """Unsupported python version according to Requires-Python package
632 | metadata."""
633 |
634 |
635 | class ConfigurationFileCouldNotBeLoaded(ConfigurationError):
636 | """When there are errors while loading a configuration file"""
637 |
638 | def __init__(
639 | self,
640 | reason: str = "could not be loaded",
641 | fname: Optional[str] = None,
642 | error: Optional[configparser.Error] = None,
643 | ) -> None:
644 | super().__init__(error)
645 | self.reason = reason
646 | self.fname = fname
647 | self.error = error
648 |
649 | def __str__(self) -> str:
650 | if self.fname is not None:
651 | message_part = f" in {self.fname}."
652 | else:
653 | assert self.error is not None
654 | message_part = f".\n{self.error}\n"
655 | return f"Configuration file {self.reason}{message_part}"
656 |
657 |
658 | _DEFAULT_EXTERNALLY_MANAGED_ERROR = f"""\
659 | The Python environment under {sys.prefix} is managed externally, and may not be
660 | manipulated by the user. Please use specific tooling from the distributor of
661 | the Python installation to interact with this environment instead.
662 | """
663 |
664 |
665 | class ExternallyManagedEnvironment(DiagnosticPipError):
666 | """The current environment is externally managed.
667 |
668 | This is raised when the current environment is externally managed, as
669 | defined by `PEP 668`_. The ``EXTERNALLY-MANAGED`` configuration is checked
670 | and displayed when the error is bubbled up to the user.
671 |
672 | :param error: The error message read from ``EXTERNALLY-MANAGED``.
673 | """
674 |
675 | reference = "externally-managed-environment"
676 |
677 | def __init__(self, error: Optional[str]) -> None:
678 | if error is None:
679 | context = Text(_DEFAULT_EXTERNALLY_MANAGED_ERROR)
680 | else:
681 | context = Text(error)
682 | super().__init__(
683 | message="This environment is externally managed",
684 | context=context,
685 | note_stmt=(
686 | "If you believe this is a mistake, please contact your "
687 | "Python installation or OS distribution provider. "
688 | "You can override this, at the risk of breaking your Python "
689 | "installation or OS, by passing --break-system-packages."
690 | ),
691 | hint_stmt=Text("See PEP 668 for the detailed specification."),
692 | )
693 |
694 | @staticmethod
695 | def _iter_externally_managed_error_keys() -> Iterator[str]:
696 | # LC_MESSAGES is in POSIX, but not the C standard. The most common
697 | # platform that does not implement this category is Windows, where
698 | # using other categories for console message localization is equally
699 | # unreliable, so we fall back to the locale-less vendor message. This
700 | # can always be re-evaluated when a vendor proposes a new alternative.
701 | try:
702 | category = locale.LC_MESSAGES
703 | except AttributeError:
704 | lang: Optional[str] = None
705 | else:
706 | lang, _ = locale.getlocale(category)
707 | if lang is not None:
708 | yield f"Error-{lang}"
709 | for sep in ("-", "_"):
710 | before, found, _ = lang.partition(sep)
711 | if not found:
712 | continue
713 | yield f"Error-{before}"
714 | yield "Error"
715 |
716 | @classmethod
717 | def from_config(
718 | cls,
719 | config: Union[pathlib.Path, str],
720 | ) -> "ExternallyManagedEnvironment":
721 | parser = configparser.ConfigParser(interpolation=None)
722 | try:
723 | parser.read(config, encoding="utf-8")
724 | section = parser["externally-managed"]
725 | for key in cls._iter_externally_managed_error_keys():
726 | with contextlib.suppress(KeyError):
727 | return cls(section[key])
728 | except KeyError:
729 | pass
730 | except (OSError, UnicodeDecodeError, configparser.ParsingError):
731 | from pip._internal.utils._log import VERBOSE
732 |
733 | exc_info = logger.isEnabledFor(VERBOSE)
734 | logger.warning("Failed to read %s", config, exc_info=exc_info)
735 | return cls(None)
736 |
737 |
738 | class UninstallMissingRecord(DiagnosticPipError):
739 | reference = "uninstall-no-record-file"
740 |
741 | def __init__(self, *, distribution: "BaseDistribution") -> None:
742 | installer = distribution.installer
743 | if not installer or installer == "pip":
744 | dep = f"{distribution.raw_name}=={distribution.version}"
745 | hint = Text.assemble(
746 | "You might be able to recover from this via: ",
747 | (f"pip install --force-reinstall --no-deps {dep}", "green"),
748 | )
749 | else:
750 | hint = Text(
751 | f"The package was installed by {installer}. "
752 | "You should check if it can uninstall the package."
753 | )
754 |
755 | super().__init__(
756 | message=Text(f"Cannot uninstall {distribution}"),
757 | context=(
758 | "The package's contents are unknown: "
759 | f"no RECORD file was found for {distribution.raw_name}."
760 | ),
761 | hint_stmt=hint,
762 | )
763 |
764 |
765 | class LegacyDistutilsInstall(DiagnosticPipError):
766 | reference = "uninstall-distutils-installed-package"
767 |
768 | def __init__(self, *, distribution: "BaseDistribution") -> None:
769 | super().__init__(
770 | message=Text(f"Cannot uninstall {distribution}"),
771 | context=(
772 | "It is a distutils installed project and thus we cannot accurately "
773 | "determine which files belong to it which would lead to only a partial "
774 | "uninstall."
775 | ),
776 | hint_stmt=None,
777 | )
778 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/exceptions.py:
--------------------------------------------------------------------------------
```python
1 | """Implements a number of Python exceptions which can be raised from within
2 | a view to trigger a standard HTTP non-200 response.
3 |
4 | Usage Example
5 | -------------
6 |
7 | .. code-block:: python
8 |
9 | from werkzeug.wrappers.request import Request
10 | from werkzeug.exceptions import HTTPException, NotFound
11 |
12 | def view(request):
13 | raise NotFound()
14 |
15 | @Request.application
16 | def application(request):
17 | try:
18 | return view(request)
19 | except HTTPException as e:
20 | return e
21 |
22 | As you can see from this example those exceptions are callable WSGI
23 | applications. However, they are not Werkzeug response objects. You
24 | can get a response object by calling ``get_response()`` on a HTTP
25 | exception.
26 |
27 | Keep in mind that you may have to pass an environ (WSGI) or scope
28 | (ASGI) to ``get_response()`` because some errors fetch additional
29 | information relating to the request.
30 |
31 | If you want to hook in a different exception page to say, a 404 status
32 | code, you can add a second except for a specific subclass of an error:
33 |
34 | .. code-block:: python
35 |
36 | @Request.application
37 | def application(request):
38 | try:
39 | return view(request)
40 | except NotFound as e:
41 | return not_found(request)
42 | except HTTPException as e:
43 | return e
44 |
45 | """
46 |
47 | from __future__ import annotations
48 |
49 | import typing as t
50 | from datetime import datetime
51 |
52 | from markupsafe import escape
53 | from markupsafe import Markup
54 |
55 | from ._internal import _get_environ
56 |
57 | if t.TYPE_CHECKING:
58 | from _typeshed.wsgi import StartResponse
59 | from _typeshed.wsgi import WSGIEnvironment
60 |
61 | from .datastructures import WWWAuthenticate
62 | from .sansio.response import Response
63 | from .wrappers.request import Request as WSGIRequest
64 | from .wrappers.response import Response as WSGIResponse
65 |
66 |
67 | class HTTPException(Exception):
68 | """The base class for all HTTP exceptions. This exception can be called as a WSGI
69 | application to render a default error page or you can catch the subclasses
70 | of it independently and render nicer error messages.
71 |
72 | .. versionchanged:: 2.1
73 | Removed the ``wrap`` class method.
74 | """
75 |
76 | code: int | None = None
77 | description: str | None = None
78 |
79 | def __init__(
80 | self,
81 | description: str | None = None,
82 | response: Response | None = None,
83 | ) -> None:
84 | super().__init__()
85 | if description is not None:
86 | self.description = description
87 | self.response = response
88 |
89 | @property
90 | def name(self) -> str:
91 | """The status name."""
92 | from .http import HTTP_STATUS_CODES
93 |
94 | return HTTP_STATUS_CODES.get(self.code, "Unknown Error") # type: ignore
95 |
96 | def get_description(
97 | self,
98 | environ: WSGIEnvironment | None = None,
99 | scope: dict[str, t.Any] | None = None,
100 | ) -> str:
101 | """Get the description."""
102 | if self.description is None:
103 | description = ""
104 | else:
105 | description = self.description
106 |
107 | description = escape(description).replace("\n", Markup("<br>"))
108 | return f"<p>{description}</p>"
109 |
110 | def get_body(
111 | self,
112 | environ: WSGIEnvironment | None = None,
113 | scope: dict[str, t.Any] | None = None,
114 | ) -> str:
115 | """Get the HTML body."""
116 | return (
117 | "<!doctype html>\n"
118 | "<html lang=en>\n"
119 | f"<title>{self.code} {escape(self.name)}</title>\n"
120 | f"<h1>{escape(self.name)}</h1>\n"
121 | f"{self.get_description(environ)}\n"
122 | )
123 |
124 | def get_headers(
125 | self,
126 | environ: WSGIEnvironment | None = None,
127 | scope: dict[str, t.Any] | None = None,
128 | ) -> list[tuple[str, str]]:
129 | """Get a list of headers."""
130 | return [("Content-Type", "text/html; charset=utf-8")]
131 |
132 | def get_response(
133 | self,
134 | environ: WSGIEnvironment | WSGIRequest | None = None,
135 | scope: dict[str, t.Any] | None = None,
136 | ) -> Response:
137 | """Get a response object. If one was passed to the exception
138 | it's returned directly.
139 |
140 | :param environ: the optional environ for the request. This
141 | can be used to modify the response depending
142 | on how the request looked like.
143 | :return: a :class:`Response` object or a subclass thereof.
144 | """
145 | from .wrappers.response import Response as WSGIResponse # noqa: F811
146 |
147 | if self.response is not None:
148 | return self.response
149 | if environ is not None:
150 | environ = _get_environ(environ)
151 | headers = self.get_headers(environ, scope)
152 | return WSGIResponse(self.get_body(environ, scope), self.code, headers)
153 |
154 | def __call__(
155 | self, environ: WSGIEnvironment, start_response: StartResponse
156 | ) -> t.Iterable[bytes]:
157 | """Call the exception as WSGI application.
158 |
159 | :param environ: the WSGI environment.
160 | :param start_response: the response callable provided by the WSGI
161 | server.
162 | """
163 | response = t.cast("WSGIResponse", self.get_response(environ))
164 | return response(environ, start_response)
165 |
166 | def __str__(self) -> str:
167 | code = self.code if self.code is not None else "???"
168 | return f"{code} {self.name}: {self.description}"
169 |
170 | def __repr__(self) -> str:
171 | code = self.code if self.code is not None else "???"
172 | return f"<{type(self).__name__} '{code}: {self.name}'>"
173 |
174 |
175 | class BadRequest(HTTPException):
176 | """*400* `Bad Request`
177 |
178 | Raise if the browser sends something to the application the application
179 | or server cannot handle.
180 | """
181 |
182 | code = 400
183 | description = (
184 | "The browser (or proxy) sent a request that this server could "
185 | "not understand."
186 | )
187 |
188 |
189 | class BadRequestKeyError(BadRequest, KeyError):
190 | """An exception that is used to signal both a :exc:`KeyError` and a
191 | :exc:`BadRequest`. Used by many of the datastructures.
192 | """
193 |
194 | _description = BadRequest.description
195 | #: Show the KeyError along with the HTTP error message in the
196 | #: response. This should be disabled in production, but can be
197 | #: useful in a debug mode.
198 | show_exception = False
199 |
200 | def __init__(self, arg: str | None = None, *args: t.Any, **kwargs: t.Any):
201 | super().__init__(*args, **kwargs)
202 |
203 | if arg is None:
204 | KeyError.__init__(self)
205 | else:
206 | KeyError.__init__(self, arg)
207 |
208 | @property # type: ignore
209 | def description(self) -> str:
210 | if self.show_exception:
211 | return (
212 | f"{self._description}\n"
213 | f"{KeyError.__name__}: {KeyError.__str__(self)}"
214 | )
215 |
216 | return self._description
217 |
218 | @description.setter
219 | def description(self, value: str) -> None:
220 | self._description = value
221 |
222 |
223 | class ClientDisconnected(BadRequest):
224 | """Internal exception that is raised if Werkzeug detects a disconnected
225 | client. Since the client is already gone at that point attempting to
226 | send the error message to the client might not work and might ultimately
227 | result in another exception in the server. Mainly this is here so that
228 | it is silenced by default as far as Werkzeug is concerned.
229 |
230 | Since disconnections cannot be reliably detected and are unspecified
231 | by WSGI to a large extent this might or might not be raised if a client
232 | is gone.
233 |
234 | .. versionadded:: 0.8
235 | """
236 |
237 |
238 | class SecurityError(BadRequest):
239 | """Raised if something triggers a security error. This is otherwise
240 | exactly like a bad request error.
241 |
242 | .. versionadded:: 0.9
243 | """
244 |
245 |
246 | class BadHost(BadRequest):
247 | """Raised if the submitted host is badly formatted.
248 |
249 | .. versionadded:: 0.11.2
250 | """
251 |
252 |
253 | class Unauthorized(HTTPException):
254 | """*401* ``Unauthorized``
255 |
256 | Raise if the user is not authorized to access a resource.
257 |
258 | The ``www_authenticate`` argument should be used to set the
259 | ``WWW-Authenticate`` header. This is used for HTTP basic auth and
260 | other schemes. Use :class:`~werkzeug.datastructures.WWWAuthenticate`
261 | to create correctly formatted values. Strictly speaking a 401
262 | response is invalid if it doesn't provide at least one value for
263 | this header, although real clients typically don't care.
264 |
265 | :param description: Override the default message used for the body
266 | of the response.
267 | :param www-authenticate: A single value, or list of values, for the
268 | WWW-Authenticate header(s).
269 |
270 | .. versionchanged:: 2.0
271 | Serialize multiple ``www_authenticate`` items into multiple
272 | ``WWW-Authenticate`` headers, rather than joining them
273 | into a single value, for better interoperability.
274 |
275 | .. versionchanged:: 0.15.3
276 | If the ``www_authenticate`` argument is not set, the
277 | ``WWW-Authenticate`` header is not set.
278 |
279 | .. versionchanged:: 0.15.3
280 | The ``response`` argument was restored.
281 |
282 | .. versionchanged:: 0.15.1
283 | ``description`` was moved back as the first argument, restoring
284 | its previous position.
285 |
286 | .. versionchanged:: 0.15.0
287 | ``www_authenticate`` was added as the first argument, ahead of
288 | ``description``.
289 | """
290 |
291 | code = 401
292 | description = (
293 | "The server could not verify that you are authorized to access"
294 | " the URL requested. You either supplied the wrong credentials"
295 | " (e.g. a bad password), or your browser doesn't understand"
296 | " how to supply the credentials required."
297 | )
298 |
299 | def __init__(
300 | self,
301 | description: str | None = None,
302 | response: Response | None = None,
303 | www_authenticate: None | (WWWAuthenticate | t.Iterable[WWWAuthenticate]) = None,
304 | ) -> None:
305 | super().__init__(description, response)
306 |
307 | from .datastructures import WWWAuthenticate
308 |
309 | if isinstance(www_authenticate, WWWAuthenticate):
310 | www_authenticate = (www_authenticate,)
311 |
312 | self.www_authenticate = www_authenticate
313 |
314 | def get_headers(
315 | self,
316 | environ: WSGIEnvironment | None = None,
317 | scope: dict[str, t.Any] | None = None,
318 | ) -> list[tuple[str, str]]:
319 | headers = super().get_headers(environ, scope)
320 | if self.www_authenticate:
321 | headers.extend(("WWW-Authenticate", str(x)) for x in self.www_authenticate)
322 | return headers
323 |
324 |
325 | class Forbidden(HTTPException):
326 | """*403* `Forbidden`
327 |
328 | Raise if the user doesn't have the permission for the requested resource
329 | but was authenticated.
330 | """
331 |
332 | code = 403
333 | description = (
334 | "You don't have the permission to access the requested"
335 | " resource. It is either read-protected or not readable by the"
336 | " server."
337 | )
338 |
339 |
340 | class NotFound(HTTPException):
341 | """*404* `Not Found`
342 |
343 | Raise if a resource does not exist and never existed.
344 | """
345 |
346 | code = 404
347 | description = (
348 | "The requested URL was not found on the server. If you entered"
349 | " the URL manually please check your spelling and try again."
350 | )
351 |
352 |
353 | class MethodNotAllowed(HTTPException):
354 | """*405* `Method Not Allowed`
355 |
356 | Raise if the server used a method the resource does not handle. For
357 | example `POST` if the resource is view only. Especially useful for REST.
358 |
359 | The first argument for this exception should be a list of allowed methods.
360 | Strictly speaking the response would be invalid if you don't provide valid
361 | methods in the header which you can do with that list.
362 | """
363 |
364 | code = 405
365 | description = "The method is not allowed for the requested URL."
366 |
367 | def __init__(
368 | self,
369 | valid_methods: t.Iterable[str] | None = None,
370 | description: str | None = None,
371 | response: Response | None = None,
372 | ) -> None:
373 | """Takes an optional list of valid http methods
374 | starting with werkzeug 0.3 the list will be mandatory."""
375 | super().__init__(description=description, response=response)
376 | self.valid_methods = valid_methods
377 |
378 | def get_headers(
379 | self,
380 | environ: WSGIEnvironment | None = None,
381 | scope: dict[str, t.Any] | None = None,
382 | ) -> list[tuple[str, str]]:
383 | headers = super().get_headers(environ, scope)
384 | if self.valid_methods:
385 | headers.append(("Allow", ", ".join(self.valid_methods)))
386 | return headers
387 |
388 |
389 | class NotAcceptable(HTTPException):
390 | """*406* `Not Acceptable`
391 |
392 | Raise if the server can't return any content conforming to the
393 | `Accept` headers of the client.
394 | """
395 |
396 | code = 406
397 | description = (
398 | "The resource identified by the request is only capable of"
399 | " generating response entities which have content"
400 | " characteristics not acceptable according to the accept"
401 | " headers sent in the request."
402 | )
403 |
404 |
405 | class RequestTimeout(HTTPException):
406 | """*408* `Request Timeout`
407 |
408 | Raise to signalize a timeout.
409 | """
410 |
411 | code = 408
412 | description = (
413 | "The server closed the network connection because the browser"
414 | " didn't finish the request within the specified time."
415 | )
416 |
417 |
418 | class Conflict(HTTPException):
419 | """*409* `Conflict`
420 |
421 | Raise to signal that a request cannot be completed because it conflicts
422 | with the current state on the server.
423 |
424 | .. versionadded:: 0.7
425 | """
426 |
427 | code = 409
428 | description = (
429 | "A conflict happened while processing the request. The"
430 | " resource might have been modified while the request was being"
431 | " processed."
432 | )
433 |
434 |
435 | class Gone(HTTPException):
436 | """*410* `Gone`
437 |
438 | Raise if a resource existed previously and went away without new location.
439 | """
440 |
441 | code = 410
442 | description = (
443 | "The requested URL is no longer available on this server and"
444 | " there is no forwarding address. If you followed a link from a"
445 | " foreign page, please contact the author of this page."
446 | )
447 |
448 |
449 | class LengthRequired(HTTPException):
450 | """*411* `Length Required`
451 |
452 | Raise if the browser submitted data but no ``Content-Length`` header which
453 | is required for the kind of processing the server does.
454 | """
455 |
456 | code = 411
457 | description = (
458 | "A request with this method requires a valid <code>Content-"
459 | "Length</code> header."
460 | )
461 |
462 |
463 | class PreconditionFailed(HTTPException):
464 | """*412* `Precondition Failed`
465 |
466 | Status code used in combination with ``If-Match``, ``If-None-Match``, or
467 | ``If-Unmodified-Since``.
468 | """
469 |
470 | code = 412
471 | description = (
472 | "The precondition on the request for the URL failed positive evaluation."
473 | )
474 |
475 |
476 | class RequestEntityTooLarge(HTTPException):
477 | """*413* `Request Entity Too Large`
478 |
479 | The status code one should return if the data submitted exceeded a given
480 | limit.
481 | """
482 |
483 | code = 413
484 | description = "The data value transmitted exceeds the capacity limit."
485 |
486 |
487 | class RequestURITooLarge(HTTPException):
488 | """*414* `Request URI Too Large`
489 |
490 | Like *413* but for too long URLs.
491 | """
492 |
493 | code = 414
494 | description = (
495 | "The length of the requested URL exceeds the capacity limit for"
496 | " this server. The request cannot be processed."
497 | )
498 |
499 |
500 | class UnsupportedMediaType(HTTPException):
501 | """*415* `Unsupported Media Type`
502 |
503 | The status code returned if the server is unable to handle the media type
504 | the client transmitted.
505 | """
506 |
507 | code = 415
508 | description = (
509 | "The server does not support the media type transmitted in the request."
510 | )
511 |
512 |
513 | class RequestedRangeNotSatisfiable(HTTPException):
514 | """*416* `Requested Range Not Satisfiable`
515 |
516 | The client asked for an invalid part of the file.
517 |
518 | .. versionadded:: 0.7
519 | """
520 |
521 | code = 416
522 | description = "The server cannot provide the requested range."
523 |
524 | def __init__(
525 | self,
526 | length: int | None = None,
527 | units: str = "bytes",
528 | description: str | None = None,
529 | response: Response | None = None,
530 | ) -> None:
531 | """Takes an optional `Content-Range` header value based on ``length``
532 | parameter.
533 | """
534 | super().__init__(description=description, response=response)
535 | self.length = length
536 | self.units = units
537 |
538 | def get_headers(
539 | self,
540 | environ: WSGIEnvironment | None = None,
541 | scope: dict[str, t.Any] | None = None,
542 | ) -> list[tuple[str, str]]:
543 | headers = super().get_headers(environ, scope)
544 | if self.length is not None:
545 | headers.append(("Content-Range", f"{self.units} */{self.length}"))
546 | return headers
547 |
548 |
549 | class ExpectationFailed(HTTPException):
550 | """*417* `Expectation Failed`
551 |
552 | The server cannot meet the requirements of the Expect request-header.
553 |
554 | .. versionadded:: 0.7
555 | """
556 |
557 | code = 417
558 | description = "The server could not meet the requirements of the Expect header"
559 |
560 |
561 | class ImATeapot(HTTPException):
562 | """*418* `I'm a teapot`
563 |
564 | The server should return this if it is a teapot and someone attempted
565 | to brew coffee with it.
566 |
567 | .. versionadded:: 0.7
568 | """
569 |
570 | code = 418
571 | description = "This server is a teapot, not a coffee machine"
572 |
573 |
574 | class UnprocessableEntity(HTTPException):
575 | """*422* `Unprocessable Entity`
576 |
577 | Used if the request is well formed, but the instructions are otherwise
578 | incorrect.
579 | """
580 |
581 | code = 422
582 | description = (
583 | "The request was well-formed but was unable to be followed due"
584 | " to semantic errors."
585 | )
586 |
587 |
588 | class Locked(HTTPException):
589 | """*423* `Locked`
590 |
591 | Used if the resource that is being accessed is locked.
592 | """
593 |
594 | code = 423
595 | description = "The resource that is being accessed is locked."
596 |
597 |
598 | class FailedDependency(HTTPException):
599 | """*424* `Failed Dependency`
600 |
601 | Used if the method could not be performed on the resource
602 | because the requested action depended on another action and that action failed.
603 | """
604 |
605 | code = 424
606 | description = (
607 | "The method could not be performed on the resource because the"
608 | " requested action depended on another action and that action"
609 | " failed."
610 | )
611 |
612 |
613 | class PreconditionRequired(HTTPException):
614 | """*428* `Precondition Required`
615 |
616 | The server requires this request to be conditional, typically to prevent
617 | the lost update problem, which is a race condition between two or more
618 | clients attempting to update a resource through PUT or DELETE. By requiring
619 | each client to include a conditional header ("If-Match" or "If-Unmodified-
620 | Since") with the proper value retained from a recent GET request, the
621 | server ensures that each client has at least seen the previous revision of
622 | the resource.
623 | """
624 |
625 | code = 428
626 | description = (
627 | "This request is required to be conditional; try using"
628 | ' "If-Match" or "If-Unmodified-Since".'
629 | )
630 |
631 |
632 | class _RetryAfter(HTTPException):
633 | """Adds an optional ``retry_after`` parameter which will set the
634 | ``Retry-After`` header. May be an :class:`int` number of seconds or
635 | a :class:`~datetime.datetime`.
636 | """
637 |
638 | def __init__(
639 | self,
640 | description: str | None = None,
641 | response: Response | None = None,
642 | retry_after: datetime | int | None = None,
643 | ) -> None:
644 | super().__init__(description, response)
645 | self.retry_after = retry_after
646 |
647 | def get_headers(
648 | self,
649 | environ: WSGIEnvironment | None = None,
650 | scope: dict[str, t.Any] | None = None,
651 | ) -> list[tuple[str, str]]:
652 | headers = super().get_headers(environ, scope)
653 |
654 | if self.retry_after:
655 | if isinstance(self.retry_after, datetime):
656 | from .http import http_date
657 |
658 | value = http_date(self.retry_after)
659 | else:
660 | value = str(self.retry_after)
661 |
662 | headers.append(("Retry-After", value))
663 |
664 | return headers
665 |
666 |
667 | class TooManyRequests(_RetryAfter):
668 | """*429* `Too Many Requests`
669 |
670 | The server is limiting the rate at which this user receives
671 | responses, and this request exceeds that rate. (The server may use
672 | any convenient method to identify users and their request rates).
673 | The server may include a "Retry-After" header to indicate how long
674 | the user should wait before retrying.
675 |
676 | :param retry_after: If given, set the ``Retry-After`` header to this
677 | value. May be an :class:`int` number of seconds or a
678 | :class:`~datetime.datetime`.
679 |
680 | .. versionchanged:: 1.0
681 | Added ``retry_after`` parameter.
682 | """
683 |
684 | code = 429
685 | description = "This user has exceeded an allotted request count. Try again later."
686 |
687 |
688 | class RequestHeaderFieldsTooLarge(HTTPException):
689 | """*431* `Request Header Fields Too Large`
690 |
691 | The server refuses to process the request because the header fields are too
692 | large. One or more individual fields may be too large, or the set of all
693 | headers is too large.
694 | """
695 |
696 | code = 431
697 | description = "One or more header fields exceeds the maximum size."
698 |
699 |
700 | class UnavailableForLegalReasons(HTTPException):
701 | """*451* `Unavailable For Legal Reasons`
702 |
703 | This status code indicates that the server is denying access to the
704 | resource as a consequence of a legal demand.
705 | """
706 |
707 | code = 451
708 | description = "Unavailable for legal reasons."
709 |
710 |
711 | class InternalServerError(HTTPException):
712 | """*500* `Internal Server Error`
713 |
714 | Raise if an internal server error occurred. This is a good fallback if an
715 | unknown error occurred in the dispatcher.
716 |
717 | .. versionchanged:: 1.0.0
718 | Added the :attr:`original_exception` attribute.
719 | """
720 |
721 | code = 500
722 | description = (
723 | "The server encountered an internal error and was unable to"
724 | " complete your request. Either the server is overloaded or"
725 | " there is an error in the application."
726 | )
727 |
728 | def __init__(
729 | self,
730 | description: str | None = None,
731 | response: Response | None = None,
732 | original_exception: BaseException | None = None,
733 | ) -> None:
734 | #: The original exception that caused this 500 error. Can be
735 | #: used by frameworks to provide context when handling
736 | #: unexpected errors.
737 | self.original_exception = original_exception
738 | super().__init__(description=description, response=response)
739 |
740 |
741 | class NotImplemented(HTTPException):
742 | """*501* `Not Implemented`
743 |
744 | Raise if the application does not support the action requested by the
745 | browser.
746 | """
747 |
748 | code = 501
749 | description = "The server does not support the action requested by the browser."
750 |
751 |
752 | class BadGateway(HTTPException):
753 | """*502* `Bad Gateway`
754 |
755 | If you do proxying in your application you should return this status code
756 | if you received an invalid response from the upstream server it accessed
757 | in attempting to fulfill the request.
758 | """
759 |
760 | code = 502
761 | description = (
762 | "The proxy server received an invalid response from an upstream server."
763 | )
764 |
765 |
766 | class ServiceUnavailable(_RetryAfter):
767 | """*503* `Service Unavailable`
768 |
769 | Status code you should return if a service is temporarily
770 | unavailable.
771 |
772 | :param retry_after: If given, set the ``Retry-After`` header to this
773 | value. May be an :class:`int` number of seconds or a
774 | :class:`~datetime.datetime`.
775 |
776 | .. versionchanged:: 1.0
777 | Added ``retry_after`` parameter.
778 | """
779 |
780 | code = 503
781 | description = (
782 | "The server is temporarily unable to service your request due"
783 | " to maintenance downtime or capacity problems. Please try"
784 | " again later."
785 | )
786 |
787 |
788 | class GatewayTimeout(HTTPException):
789 | """*504* `Gateway Timeout`
790 |
791 | Status code you should return if a connection to an upstream server
792 | times out.
793 | """
794 |
795 | code = 504
796 | description = "The connection to an upstream server timed out."
797 |
798 |
799 | class HTTPVersionNotSupported(HTTPException):
800 | """*505* `HTTP Version Not Supported`
801 |
802 | The server does not support the HTTP protocol version used in the request.
803 | """
804 |
805 | code = 505
806 | description = (
807 | "The server does not support the HTTP protocol version used in the request."
808 | )
809 |
810 |
811 | default_exceptions: dict[int, type[HTTPException]] = {}
812 |
813 |
814 | def _find_exceptions() -> None:
815 | for obj in globals().values():
816 | try:
817 | is_http_exception = issubclass(obj, HTTPException)
818 | except TypeError:
819 | is_http_exception = False
820 | if not is_http_exception or obj.code is None:
821 | continue
822 | old_obj = default_exceptions.get(obj.code, None)
823 | if old_obj is not None and issubclass(obj, old_obj):
824 | continue
825 | default_exceptions[obj.code] = obj
826 |
827 |
828 | _find_exceptions()
829 | del _find_exceptions
830 |
831 |
832 | class Aborter:
833 | """When passed a dict of code -> exception items it can be used as
834 | callable that raises exceptions. If the first argument to the
835 | callable is an integer it will be looked up in the mapping, if it's
836 | a WSGI application it will be raised in a proxy exception.
837 |
838 | The rest of the arguments are forwarded to the exception constructor.
839 | """
840 |
841 | def __init__(
842 | self,
843 | mapping: dict[int, type[HTTPException]] | None = None,
844 | extra: dict[int, type[HTTPException]] | None = None,
845 | ) -> None:
846 | if mapping is None:
847 | mapping = default_exceptions
848 | self.mapping = dict(mapping)
849 | if extra is not None:
850 | self.mapping.update(extra)
851 |
852 | def __call__(
853 | self, code: int | Response, *args: t.Any, **kwargs: t.Any
854 | ) -> t.NoReturn:
855 | from .sansio.response import Response
856 |
857 | if isinstance(code, Response):
858 | raise HTTPException(response=code)
859 |
860 | if code not in self.mapping:
861 | raise LookupError(f"no exception for {code!r}")
862 |
863 | raise self.mapping[code](*args, **kwargs)
864 |
865 |
866 | def abort(status: int | Response, *args: t.Any, **kwargs: t.Any) -> t.NoReturn:
867 | """Raises an :py:exc:`HTTPException` for the given status code or WSGI
868 | application.
869 |
870 | If a status code is given, it will be looked up in the list of
871 | exceptions and will raise that exception. If passed a WSGI application,
872 | it will wrap it in a proxy WSGI exception and raise that::
873 |
874 | abort(404) # 404 Not Found
875 | abort(Response('Hello World'))
876 |
877 | """
878 | _aborter(status, *args, **kwargs)
879 |
880 |
881 | _aborter: Aborter = Aborter()
882 |
```