This is page 76 of 168. Use http://codebase.md/romanshablio/mcp_server?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .DS_Store
├── .venv
│ ├── __pycache__
│ │ └── hello.cpython-312.pyc
│ ├── bin
│ │ ├── activate
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── Activate.ps1
│ │ ├── flask
│ │ ├── normalizer
│ │ ├── pip
│ │ ├── pip3
│ │ ├── pip3.12
│ │ ├── python
│ │ ├── python3
│ │ └── python3.12
│ ├── hello.py
│ ├── lib
│ │ └── python3.12
│ │ └── site-packages
│ │ ├── beautifulsoup4-4.12.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ ├── AUTHORS
│ │ │ │ └── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── blinker
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _utilities.cpython-312.pyc
│ │ │ │ └── base.cpython-312.pyc
│ │ │ ├── _utilities.py
│ │ │ ├── base.py
│ │ │ └── py.typed
│ │ ├── blinker-1.8.2.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── bs4
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── css.cpython-312.pyc
│ │ │ │ ├── dammit.cpython-312.pyc
│ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ ├── element.cpython-312.pyc
│ │ │ │ └── formatter.cpython-312.pyc
│ │ │ ├── builder
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _html5lib.cpython-312.pyc
│ │ │ │ │ ├── _htmlparser.cpython-312.pyc
│ │ │ │ │ └── _lxml.cpython-312.pyc
│ │ │ │ ├── _html5lib.py
│ │ │ │ ├── _htmlparser.py
│ │ │ │ └── _lxml.py
│ │ │ ├── css.py
│ │ │ ├── dammit.py
│ │ │ ├── diagnose.py
│ │ │ ├── element.py
│ │ │ ├── formatter.py
│ │ │ └── tests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── test_builder_registry.cpython-312.pyc
│ │ │ │ ├── test_builder.cpython-312.pyc
│ │ │ │ ├── test_css.cpython-312.pyc
│ │ │ │ ├── test_dammit.cpython-312.pyc
│ │ │ │ ├── test_docs.cpython-312.pyc
│ │ │ │ ├── test_element.cpython-312.pyc
│ │ │ │ ├── test_formatter.cpython-312.pyc
│ │ │ │ ├── test_fuzz.cpython-312.pyc
│ │ │ │ ├── test_html5lib.cpython-312.pyc
│ │ │ │ ├── test_htmlparser.cpython-312.pyc
│ │ │ │ ├── test_lxml.cpython-312.pyc
│ │ │ │ ├── test_navigablestring.cpython-312.pyc
│ │ │ │ ├── test_pageelement.cpython-312.pyc
│ │ │ │ ├── test_soup.cpython-312.pyc
│ │ │ │ ├── test_tag.cpython-312.pyc
│ │ │ │ └── test_tree.cpython-312.pyc
│ │ │ ├── fuzz
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase
│ │ │ │ ├── crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase
│ │ │ │ └── crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase
│ │ │ ├── test_builder_registry.py
│ │ │ ├── test_builder.py
│ │ │ ├── test_css.py
│ │ │ ├── test_dammit.py
│ │ │ ├── test_docs.py
│ │ │ ├── test_element.py
│ │ │ ├── test_formatter.py
│ │ │ ├── test_fuzz.py
│ │ │ ├── test_html5lib.py
│ │ │ ├── test_htmlparser.py
│ │ │ ├── test_lxml.py
│ │ │ ├── test_navigablestring.py
│ │ │ ├── test_pageelement.py
│ │ │ ├── test_soup.py
│ │ │ ├── test_tag.py
│ │ │ └── test_tree.py
│ │ ├── certifi
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── core.cpython-312.pyc
│ │ │ ├── cacert.pem
│ │ │ ├── core.py
│ │ │ └── py.typed
│ │ ├── certifi-2024.8.30.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── charset_normalizer
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── cd.cpython-312.pyc
│ │ │ │ ├── constant.cpython-312.pyc
│ │ │ │ ├── legacy.cpython-312.pyc
│ │ │ │ ├── md.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── version.cpython-312.pyc
│ │ │ ├── api.py
│ │ │ ├── cd.py
│ │ │ ├── cli
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── __main__.cpython-312.pyc
│ │ │ ├── constant.py
│ │ │ ├── legacy.py
│ │ │ ├── md__mypyc.cpython-312-darwin.so
│ │ │ ├── md.cpython-312-darwin.so
│ │ │ ├── md.py
│ │ │ ├── models.py
│ │ │ ├── py.typed
│ │ │ ├── utils.py
│ │ │ └── version.py
│ │ ├── charset_normalizer-3.4.0.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── click
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ ├── _termui_impl.cpython-312.pyc
│ │ │ │ ├── _textwrap.cpython-312.pyc
│ │ │ │ ├── _winconsole.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── decorators.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formatting.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── shell_completion.cpython-312.pyc
│ │ │ │ ├── termui.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── types.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── _compat.py
│ │ │ ├── _termui_impl.py
│ │ │ ├── _textwrap.py
│ │ │ ├── _winconsole.py
│ │ │ ├── core.py
│ │ │ ├── decorators.py
│ │ │ ├── exceptions.py
│ │ │ ├── formatting.py
│ │ │ ├── globals.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── shell_completion.py
│ │ │ ├── termui.py
│ │ │ ├── testing.py
│ │ │ ├── types.py
│ │ │ └── utils.py
│ │ ├── click-8.1.7.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.rst
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── fake_useragent
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ ├── fake.cpython-312.pyc
│ │ │ │ ├── log.cpython-312.pyc
│ │ │ │ ├── settings.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── data
│ │ │ │ └── browsers.json
│ │ │ ├── errors.py
│ │ │ ├── fake.py
│ │ │ ├── log.py
│ │ │ ├── settings.py
│ │ │ └── utils.py
│ │ ├── fake_useragent-1.5.1.dist-info
│ │ │ ├── AUTHORS
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── flask
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ ├── cli.cpython-312.pyc
│ │ │ │ ├── config.cpython-312.pyc
│ │ │ │ ├── ctx.cpython-312.pyc
│ │ │ │ ├── debughelpers.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── helpers.cpython-312.pyc
│ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── signals.cpython-312.pyc
│ │ │ │ ├── templating.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── typing.cpython-312.pyc
│ │ │ │ ├── views.cpython-312.pyc
│ │ │ │ └── wrappers.cpython-312.pyc
│ │ │ ├── app.py
│ │ │ ├── blueprints.py
│ │ │ ├── cli.py
│ │ │ ├── config.py
│ │ │ ├── ctx.py
│ │ │ ├── debughelpers.py
│ │ │ ├── globals.py
│ │ │ ├── helpers.py
│ │ │ ├── json
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ └── tag.cpython-312.pyc
│ │ │ │ ├── provider.py
│ │ │ │ └── tag.py
│ │ │ ├── logging.py
│ │ │ ├── py.typed
│ │ │ ├── sansio
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ │ └── scaffold.cpython-312.pyc
│ │ │ │ ├── app.py
│ │ │ │ ├── blueprints.py
│ │ │ │ ├── README.md
│ │ │ │ └── scaffold.py
│ │ │ ├── sessions.py
│ │ │ ├── signals.py
│ │ │ ├── templating.py
│ │ │ ├── testing.py
│ │ │ ├── typing.py
│ │ │ ├── views.py
│ │ │ └── wrappers.py
│ │ ├── flask-3.0.3.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── idna
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ ├── codec.py
│ │ │ ├── compat.py
│ │ │ ├── core.py
│ │ │ ├── idnadata.py
│ │ │ ├── intranges.py
│ │ │ ├── package_data.py
│ │ │ ├── py.typed
│ │ │ └── uts46data.py
│ │ ├── idna-3.10.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── itsdangerous
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ ├── exc.cpython-312.pyc
│ │ │ │ ├── serializer.cpython-312.pyc
│ │ │ │ ├── signer.cpython-312.pyc
│ │ │ │ ├── timed.cpython-312.pyc
│ │ │ │ └── url_safe.cpython-312.pyc
│ │ │ ├── _json.py
│ │ │ ├── encoding.py
│ │ │ ├── exc.py
│ │ │ ├── py.typed
│ │ │ ├── serializer.py
│ │ │ ├── signer.py
│ │ │ ├── timed.py
│ │ │ └── url_safe.py
│ │ ├── itsdangerous-2.2.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── jinja2
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _identifier.cpython-312.pyc
│ │ │ │ ├── async_utils.cpython-312.pyc
│ │ │ │ ├── bccache.cpython-312.pyc
│ │ │ │ ├── compiler.cpython-312.pyc
│ │ │ │ ├── constants.cpython-312.pyc
│ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ ├── defaults.cpython-312.pyc
│ │ │ │ ├── environment.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ ├── filters.cpython-312.pyc
│ │ │ │ ├── idtracking.cpython-312.pyc
│ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ ├── loaders.cpython-312.pyc
│ │ │ │ ├── meta.cpython-312.pyc
│ │ │ │ ├── nativetypes.cpython-312.pyc
│ │ │ │ ├── nodes.cpython-312.pyc
│ │ │ │ ├── optimizer.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── runtime.cpython-312.pyc
│ │ │ │ ├── sandbox.cpython-312.pyc
│ │ │ │ ├── tests.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── visitor.cpython-312.pyc
│ │ │ ├── _identifier.py
│ │ │ ├── async_utils.py
│ │ │ ├── bccache.py
│ │ │ ├── compiler.py
│ │ │ ├── constants.py
│ │ │ ├── debug.py
│ │ │ ├── defaults.py
│ │ │ ├── environment.py
│ │ │ ├── exceptions.py
│ │ │ ├── ext.py
│ │ │ ├── filters.py
│ │ │ ├── idtracking.py
│ │ │ ├── lexer.py
│ │ │ ├── loaders.py
│ │ │ ├── meta.py
│ │ │ ├── nativetypes.py
│ │ │ ├── nodes.py
│ │ │ ├── optimizer.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── runtime.py
│ │ │ ├── sandbox.py
│ │ │ ├── tests.py
│ │ │ ├── utils.py
│ │ │ └── visitor.py
│ │ ├── jinja2-3.1.4.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── lxml
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _elementpath.cpython-312.pyc
│ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ ├── cssselect.cpython-312.pyc
│ │ │ │ ├── doctestcompare.cpython-312.pyc
│ │ │ │ ├── ElementInclude.cpython-312.pyc
│ │ │ │ ├── pyclasslookup.cpython-312.pyc
│ │ │ │ ├── sax.cpython-312.pyc
│ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ ├── _elementpath.cpython-312-darwin.so
│ │ │ ├── _elementpath.py
│ │ │ ├── apihelpers.pxi
│ │ │ ├── builder.cpython-312-darwin.so
│ │ │ ├── builder.py
│ │ │ ├── classlookup.pxi
│ │ │ ├── cleanup.pxi
│ │ │ ├── cssselect.py
│ │ │ ├── debug.pxi
│ │ │ ├── docloader.pxi
│ │ │ ├── doctestcompare.py
│ │ │ ├── dtd.pxi
│ │ │ ├── ElementInclude.py
│ │ │ ├── etree_api.h
│ │ │ ├── etree.cpython-312-darwin.so
│ │ │ ├── etree.h
│ │ │ ├── etree.pyx
│ │ │ ├── extensions.pxi
│ │ │ ├── html
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _diffcommand.cpython-312.pyc
│ │ │ │ │ ├── _html5builder.cpython-312.pyc
│ │ │ │ │ ├── _setmixin.cpython-312.pyc
│ │ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ │ ├── clean.cpython-312.pyc
│ │ │ │ │ ├── defs.cpython-312.pyc
│ │ │ │ │ ├── diff.cpython-312.pyc
│ │ │ │ │ ├── ElementSoup.cpython-312.pyc
│ │ │ │ │ ├── formfill.cpython-312.pyc
│ │ │ │ │ ├── html5parser.cpython-312.pyc
│ │ │ │ │ ├── soupparser.cpython-312.pyc
│ │ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ │ ├── _diffcommand.py
│ │ │ │ ├── _html5builder.py
│ │ │ │ ├── _setmixin.py
│ │ │ │ ├── builder.py
│ │ │ │ ├── clean.py
│ │ │ │ ├── defs.py
│ │ │ │ ├── diff.cpython-312-darwin.so
│ │ │ │ ├── diff.py
│ │ │ │ ├── ElementSoup.py
│ │ │ │ ├── formfill.py
│ │ │ │ ├── html5parser.py
│ │ │ │ ├── soupparser.py
│ │ │ │ └── usedoctest.py
│ │ │ ├── includes
│ │ │ │ ├── __init__.pxd
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── c14n.pxd
│ │ │ │ ├── config.pxd
│ │ │ │ ├── dtdvalid.pxd
│ │ │ │ ├── etree_defs.h
│ │ │ │ ├── etreepublic.pxd
│ │ │ │ ├── extlibs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── libcharset.h
│ │ │ │ │ ├── localcharset.h
│ │ │ │ │ ├── zconf.h
│ │ │ │ │ └── zlib.h
│ │ │ │ ├── htmlparser.pxd
│ │ │ │ ├── libexslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── exslt.h
│ │ │ │ │ ├── exsltconfig.h
│ │ │ │ │ └── exsltexports.h
│ │ │ │ ├── libxml
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── c14n.h
│ │ │ │ │ ├── catalog.h
│ │ │ │ │ ├── chvalid.h
│ │ │ │ │ ├── debugXML.h
│ │ │ │ │ ├── dict.h
│ │ │ │ │ ├── encoding.h
│ │ │ │ │ ├── entities.h
│ │ │ │ │ ├── globals.h
│ │ │ │ │ ├── hash.h
│ │ │ │ │ ├── HTMLparser.h
│ │ │ │ │ ├── HTMLtree.h
│ │ │ │ │ ├── list.h
│ │ │ │ │ ├── nanoftp.h
│ │ │ │ │ ├── nanohttp.h
│ │ │ │ │ ├── parser.h
│ │ │ │ │ ├── parserInternals.h
│ │ │ │ │ ├── relaxng.h
│ │ │ │ │ ├── SAX.h
│ │ │ │ │ ├── SAX2.h
│ │ │ │ │ ├── schemasInternals.h
│ │ │ │ │ ├── schematron.h
│ │ │ │ │ ├── threads.h
│ │ │ │ │ ├── tree.h
│ │ │ │ │ ├── uri.h
│ │ │ │ │ ├── valid.h
│ │ │ │ │ ├── xinclude.h
│ │ │ │ │ ├── xlink.h
│ │ │ │ │ ├── xmlautomata.h
│ │ │ │ │ ├── xmlerror.h
│ │ │ │ │ ├── xmlexports.h
│ │ │ │ │ ├── xmlIO.h
│ │ │ │ │ ├── xmlmemory.h
│ │ │ │ │ ├── xmlmodule.h
│ │ │ │ │ ├── xmlreader.h
│ │ │ │ │ ├── xmlregexp.h
│ │ │ │ │ ├── xmlsave.h
│ │ │ │ │ ├── xmlschemas.h
│ │ │ │ │ ├── xmlschemastypes.h
│ │ │ │ │ ├── xmlstring.h
│ │ │ │ │ ├── xmlunicode.h
│ │ │ │ │ ├── xmlversion.h
│ │ │ │ │ ├── xmlwriter.h
│ │ │ │ │ ├── xpath.h
│ │ │ │ │ ├── xpathInternals.h
│ │ │ │ │ └── xpointer.h
│ │ │ │ ├── libxslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── attributes.h
│ │ │ │ │ ├── documents.h
│ │ │ │ │ ├── extensions.h
│ │ │ │ │ ├── extra.h
│ │ │ │ │ ├── functions.h
│ │ │ │ │ ├── imports.h
│ │ │ │ │ ├── keys.h
│ │ │ │ │ ├── namespaces.h
│ │ │ │ │ ├── numbersInternals.h
│ │ │ │ │ ├── pattern.h
│ │ │ │ │ ├── preproc.h
│ │ │ │ │ ├── security.h
│ │ │ │ │ ├── templates.h
│ │ │ │ │ ├── transform.h
│ │ │ │ │ ├── variables.h
│ │ │ │ │ ├── xslt.h
│ │ │ │ │ ├── xsltconfig.h
│ │ │ │ │ ├── xsltexports.h
│ │ │ │ │ ├── xsltInternals.h
│ │ │ │ │ ├── xsltlocale.h
│ │ │ │ │ └── xsltutils.h
│ │ │ │ ├── lxml-version.h
│ │ │ │ ├── relaxng.pxd
│ │ │ │ ├── schematron.pxd
│ │ │ │ ├── tree.pxd
│ │ │ │ ├── uri.pxd
│ │ │ │ ├── xinclude.pxd
│ │ │ │ ├── xmlerror.pxd
│ │ │ │ ├── xmlparser.pxd
│ │ │ │ ├── xmlschema.pxd
│ │ │ │ ├── xpath.pxd
│ │ │ │ └── xslt.pxd
│ │ │ ├── isoschematron
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ └── resources
│ │ │ │ ├── rng
│ │ │ │ │ └── iso-schematron.rng
│ │ │ │ └── xsl
│ │ │ │ ├── iso-schematron-xslt1
│ │ │ │ │ ├── iso_abstract_expand.xsl
│ │ │ │ │ ├── iso_dsdl_include.xsl
│ │ │ │ │ ├── iso_schematron_message.xsl
│ │ │ │ │ ├── iso_schematron_skeleton_for_xslt1.xsl
│ │ │ │ │ ├── iso_svrl_for_xslt1.xsl
│ │ │ │ │ └── readme.txt
│ │ │ │ ├── RNG2Schtrn.xsl
│ │ │ │ └── XSD2Schtrn.xsl
│ │ │ ├── iterparse.pxi
│ │ │ ├── lxml.etree_api.h
│ │ │ ├── lxml.etree.h
│ │ │ ├── nsclasses.pxi
│ │ │ ├── objectify.cpython-312-darwin.so
│ │ │ ├── objectify.pyx
│ │ │ ├── objectpath.pxi
│ │ │ ├── parser.pxi
│ │ │ ├── parsertarget.pxi
│ │ │ ├── proxy.pxi
│ │ │ ├── public-api.pxi
│ │ │ ├── pyclasslookup.py
│ │ │ ├── readonlytree.pxi
│ │ │ ├── relaxng.pxi
│ │ │ ├── sax.cpython-312-darwin.so
│ │ │ ├── sax.py
│ │ │ ├── saxparser.pxi
│ │ │ ├── schematron.pxi
│ │ │ ├── serializer.pxi
│ │ │ ├── usedoctest.py
│ │ │ ├── xinclude.pxi
│ │ │ ├── xmlerror.pxi
│ │ │ ├── xmlid.pxi
│ │ │ ├── xmlschema.pxi
│ │ │ ├── xpath.pxi
│ │ │ ├── xslt.pxi
│ │ │ └── xsltext.pxi
│ │ ├── lxml-5.3.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── LICENSES.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── markupsafe
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── _native.cpython-312.pyc
│ │ │ ├── _native.py
│ │ │ ├── _speedups.c
│ │ │ ├── _speedups.cpython-312-darwin.so
│ │ │ ├── _speedups.pyi
│ │ │ └── py.typed
│ │ ├── MarkupSafe-3.0.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── pip
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pip-runner__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── __pip-runner__.cpython-312.pyc
│ │ │ ├── _internal
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── build_env.cpython-312.pyc
│ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ ├── pyproject.cpython-312.pyc
│ │ │ │ │ ├── self_outdated_check.cpython-312.pyc
│ │ │ │ │ └── wheel_builder.cpython-312.pyc
│ │ │ │ ├── build_env.py
│ │ │ │ ├── cache.py
│ │ │ │ ├── cli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── autocompletion.cpython-312.pyc
│ │ │ │ │ │ ├── base_command.cpython-312.pyc
│ │ │ │ │ │ ├── cmdoptions.cpython-312.pyc
│ │ │ │ │ │ ├── command_context.cpython-312.pyc
│ │ │ │ │ │ ├── index_command.cpython-312.pyc
│ │ │ │ │ │ ├── main_parser.cpython-312.pyc
│ │ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bars.cpython-312.pyc
│ │ │ │ │ │ ├── req_command.cpython-312.pyc
│ │ │ │ │ │ ├── spinners.cpython-312.pyc
│ │ │ │ │ │ └── status_codes.cpython-312.pyc
│ │ │ │ │ ├── autocompletion.py
│ │ │ │ │ ├── base_command.py
│ │ │ │ │ ├── cmdoptions.py
│ │ │ │ │ ├── command_context.py
│ │ │ │ │ ├── index_command.py
│ │ │ │ │ ├── main_parser.py
│ │ │ │ │ ├── main.py
│ │ │ │ │ ├── parser.py
│ │ │ │ │ ├── progress_bars.py
│ │ │ │ │ ├── req_command.py
│ │ │ │ │ ├── spinners.py
│ │ │ │ │ └── status_codes.py
│ │ │ │ ├── commands
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── completion.cpython-312.pyc
│ │ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ ├── hash.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── inspect.cpython-312.pyc
│ │ │ │ │ │ ├── install.cpython-312.pyc
│ │ │ │ │ │ ├── list.cpython-312.pyc
│ │ │ │ │ │ ├── search.cpython-312.pyc
│ │ │ │ │ │ ├── show.cpython-312.pyc
│ │ │ │ │ │ ├── uninstall.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── completion.py
│ │ │ │ │ ├── configuration.py
│ │ │ │ │ ├── debug.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── hash.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── inspect.py
│ │ │ │ │ ├── install.py
│ │ │ │ │ ├── list.py
│ │ │ │ │ ├── search.py
│ │ │ │ │ ├── show.py
│ │ │ │ │ ├── uninstall.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── configuration.py
│ │ │ │ ├── distributions
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── installed.cpython-312.pyc
│ │ │ │ │ │ ├── sdist.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── installed.py
│ │ │ │ │ ├── sdist.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── index
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── collector.cpython-312.pyc
│ │ │ │ │ │ ├── package_finder.cpython-312.pyc
│ │ │ │ │ │ └── sources.cpython-312.pyc
│ │ │ │ │ ├── collector.py
│ │ │ │ │ ├── package_finder.py
│ │ │ │ │ └── sources.py
│ │ │ │ ├── locations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _distutils.cpython-312.pyc
│ │ │ │ │ │ ├── _sysconfig.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── _distutils.py
│ │ │ │ │ ├── _sysconfig.py
│ │ │ │ │ └── base.py
│ │ │ │ ├── main.py
│ │ │ │ ├── metadata
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ └── pkg_resources.cpython-312.pyc
│ │ │ │ │ ├── _json.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── importlib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ │ ├── _dists.cpython-312.pyc
│ │ │ │ │ │ │ └── _envs.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.py
│ │ │ │ │ │ ├── _dists.py
│ │ │ │ │ │ └── _envs.py
│ │ │ │ │ └── pkg_resources.py
│ │ │ │ ├── models
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── candidate.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url.cpython-312.pyc
│ │ │ │ │ │ ├── format_control.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── installation_report.cpython-312.pyc
│ │ │ │ │ │ ├── link.cpython-312.pyc
│ │ │ │ │ │ ├── scheme.cpython-312.pyc
│ │ │ │ │ │ ├── search_scope.cpython-312.pyc
│ │ │ │ │ │ ├── selection_prefs.cpython-312.pyc
│ │ │ │ │ │ ├── target_python.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── candidate.py
│ │ │ │ │ ├── direct_url.py
│ │ │ │ │ ├── format_control.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── installation_report.py
│ │ │ │ │ ├── link.py
│ │ │ │ │ ├── scheme.py
│ │ │ │ │ ├── search_scope.py
│ │ │ │ │ ├── selection_prefs.py
│ │ │ │ │ ├── target_python.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── network
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── lazy_wheel.cpython-312.pyc
│ │ │ │ │ │ ├── session.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── xmlrpc.cpython-312.pyc
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── lazy_wheel.py
│ │ │ │ │ ├── session.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── xmlrpc.py
│ │ │ │ ├── operations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ └── prepare.cpython-312.pyc
│ │ │ │ │ ├── build
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── build_tracker.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_legacy.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── build_tracker.py
│ │ │ │ │ │ ├── metadata_editable.py
│ │ │ │ │ │ ├── metadata_legacy.py
│ │ │ │ │ │ ├── metadata.py
│ │ │ │ │ │ ├── wheel_editable.py
│ │ │ │ │ │ ├── wheel_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── install
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── editable_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── editable_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ └── prepare.py
│ │ │ │ ├── pyproject.py
│ │ │ │ ├── req
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── constructors.cpython-312.pyc
│ │ │ │ │ │ ├── req_file.cpython-312.pyc
│ │ │ │ │ │ ├── req_install.cpython-312.pyc
│ │ │ │ │ │ ├── req_set.cpython-312.pyc
│ │ │ │ │ │ └── req_uninstall.cpython-312.pyc
│ │ │ │ │ ├── constructors.py
│ │ │ │ │ ├── req_file.py
│ │ │ │ │ ├── req_install.py
│ │ │ │ │ ├── req_set.py
│ │ │ │ │ └── req_uninstall.py
│ │ │ │ ├── resolution
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── legacy
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ │ └── resolver.py
│ │ │ │ │ └── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── candidates.cpython-312.pyc
│ │ │ │ │ │ ├── factory.cpython-312.pyc
│ │ │ │ │ │ ├── found_candidates.cpython-312.pyc
│ │ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ │ ├── reporter.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── candidates.py
│ │ │ │ │ ├── factory.py
│ │ │ │ │ ├── found_candidates.py
│ │ │ │ │ ├── provider.py
│ │ │ │ │ ├── reporter.py
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ └── resolver.py
│ │ │ │ ├── self_outdated_check.py
│ │ │ │ ├── utils
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _jaraco_text.cpython-312.pyc
│ │ │ │ │ │ ├── _log.cpython-312.pyc
│ │ │ │ │ │ ├── appdirs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── compatibility_tags.cpython-312.pyc
│ │ │ │ │ │ ├── datetime.cpython-312.pyc
│ │ │ │ │ │ ├── deprecation.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url_helpers.cpython-312.pyc
│ │ │ │ │ │ ├── egg_link.cpython-312.pyc
│ │ │ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ │ │ ├── entrypoints.cpython-312.pyc
│ │ │ │ │ │ ├── filesystem.cpython-312.pyc
│ │ │ │ │ │ ├── filetypes.cpython-312.pyc
│ │ │ │ │ │ ├── glibc.cpython-312.pyc
│ │ │ │ │ │ ├── hashes.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── misc.cpython-312.pyc
│ │ │ │ │ │ ├── packaging.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── setuptools_build.cpython-312.pyc
│ │ │ │ │ │ ├── subprocess.cpython-312.pyc
│ │ │ │ │ │ ├── temp_dir.cpython-312.pyc
│ │ │ │ │ │ ├── unpacking.cpython-312.pyc
│ │ │ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ │ │ ├── virtualenv.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── _jaraco_text.py
│ │ │ │ │ ├── _log.py
│ │ │ │ │ ├── appdirs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── compatibility_tags.py
│ │ │ │ │ ├── datetime.py
│ │ │ │ │ ├── deprecation.py
│ │ │ │ │ ├── direct_url_helpers.py
│ │ │ │ │ ├── egg_link.py
│ │ │ │ │ ├── encoding.py
│ │ │ │ │ ├── entrypoints.py
│ │ │ │ │ ├── filesystem.py
│ │ │ │ │ ├── filetypes.py
│ │ │ │ │ ├── glibc.py
│ │ │ │ │ ├── hashes.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── misc.py
│ │ │ │ │ ├── packaging.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── setuptools_build.py
│ │ │ │ │ ├── subprocess.py
│ │ │ │ │ ├── temp_dir.py
│ │ │ │ │ ├── unpacking.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ ├── virtualenv.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── vcs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── bazaar.cpython-312.pyc
│ │ │ │ │ │ ├── git.cpython-312.pyc
│ │ │ │ │ │ ├── mercurial.cpython-312.pyc
│ │ │ │ │ │ ├── subversion.cpython-312.pyc
│ │ │ │ │ │ └── versioncontrol.cpython-312.pyc
│ │ │ │ │ ├── bazaar.py
│ │ │ │ │ ├── git.py
│ │ │ │ │ ├── mercurial.py
│ │ │ │ │ ├── subversion.py
│ │ │ │ │ └── versioncontrol.py
│ │ │ │ └── wheel_builder.py
│ │ │ ├── _vendor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ └── typing_extensions.cpython-312.pyc
│ │ │ │ ├── cachecontrol
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _cmd.cpython-312.pyc
│ │ │ │ │ │ ├── adapter.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── controller.cpython-312.pyc
│ │ │ │ │ │ ├── filewrapper.cpython-312.pyc
│ │ │ │ │ │ ├── heuristics.cpython-312.pyc
│ │ │ │ │ │ ├── serialize.cpython-312.pyc
│ │ │ │ │ │ └── wrapper.cpython-312.pyc
│ │ │ │ │ ├── _cmd.py
│ │ │ │ │ ├── adapter.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── caches
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── file_cache.cpython-312.pyc
│ │ │ │ │ │ │ └── redis_cache.cpython-312.pyc
│ │ │ │ │ │ ├── file_cache.py
│ │ │ │ │ │ └── redis_cache.py
│ │ │ │ │ ├── controller.py
│ │ │ │ │ ├── filewrapper.py
│ │ │ │ │ ├── heuristics.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── serialize.py
│ │ │ │ │ └── wrapper.py
│ │ │ │ ├── certifi
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── core.cpython-312.pyc
│ │ │ │ │ ├── cacert.pem
│ │ │ │ │ ├── core.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── distlib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── database.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── locators.cpython-312.pyc
│ │ │ │ │ │ ├── manifest.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── resources.cpython-312.pyc
│ │ │ │ │ │ ├── scripts.cpython-312.pyc
│ │ │ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── database.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── locators.py
│ │ │ │ │ ├── manifest.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── resources.py
│ │ │ │ │ ├── scripts.py
│ │ │ │ │ ├── t32.exe
│ │ │ │ │ ├── t64-arm.exe
│ │ │ │ │ ├── t64.exe
│ │ │ │ │ ├── util.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ ├── w32.exe
│ │ │ │ │ ├── w64-arm.exe
│ │ │ │ │ ├── w64.exe
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── distro
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── distro.cpython-312.pyc
│ │ │ │ │ ├── distro.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── idna
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ │ │ ├── codec.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── core.py
│ │ │ │ │ ├── idnadata.py
│ │ │ │ │ ├── intranges.py
│ │ │ │ │ ├── package_data.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ └── uts46data.py
│ │ │ │ ├── msgpack
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ │ │ └── fallback.cpython-312.pyc
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── ext.py
│ │ │ │ │ └── fallback.py
│ │ │ │ ├── packaging
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _elffile.cpython-312.pyc
│ │ │ │ │ │ ├── _manylinux.cpython-312.pyc
│ │ │ │ │ │ ├── _musllinux.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _structures.cpython-312.pyc
│ │ │ │ │ │ ├── _tokenizer.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ ├── specifiers.cpython-312.pyc
│ │ │ │ │ │ ├── tags.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── version.cpython-312.pyc
│ │ │ │ │ ├── _elffile.py
│ │ │ │ │ ├── _manylinux.py
│ │ │ │ │ ├── _musllinux.py
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _structures.py
│ │ │ │ │ ├── _tokenizer.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ ├── specifiers.py
│ │ │ │ │ ├── tags.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── version.py
│ │ │ │ ├── pkg_resources
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── platformdirs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── android.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── macos.cpython-312.pyc
│ │ │ │ │ │ ├── unix.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── windows.cpython-312.pyc
│ │ │ │ │ ├── android.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── macos.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── unix.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ └── windows.py
│ │ │ │ ├── pygments
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── cmdline.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── filter.cpython-312.pyc
│ │ │ │ │ │ ├── formatter.cpython-312.pyc
│ │ │ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ │ │ ├── modeline.cpython-312.pyc
│ │ │ │ │ │ ├── plugin.cpython-312.pyc
│ │ │ │ │ │ ├── regexopt.cpython-312.pyc
│ │ │ │ │ │ ├── scanner.cpython-312.pyc
│ │ │ │ │ │ ├── sphinxext.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── token.cpython-312.pyc
│ │ │ │ │ │ ├── unistring.cpython-312.pyc
│ │ │ │ │ │ └── util.cpython-312.pyc
│ │ │ │ │ ├── cmdline.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── filter.py
│ │ │ │ │ ├── filters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── formatter.py
│ │ │ │ │ ├── formatters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ ├── bbcode.cpython-312.pyc
│ │ │ │ │ │ │ ├── groff.cpython-312.pyc
│ │ │ │ │ │ │ ├── html.cpython-312.pyc
│ │ │ │ │ │ │ ├── img.cpython-312.pyc
│ │ │ │ │ │ │ ├── irc.cpython-312.pyc
│ │ │ │ │ │ │ ├── latex.cpython-312.pyc
│ │ │ │ │ │ │ ├── other.cpython-312.pyc
│ │ │ │ │ │ │ ├── pangomarkup.cpython-312.pyc
│ │ │ │ │ │ │ ├── rtf.cpython-312.pyc
│ │ │ │ │ │ │ ├── svg.cpython-312.pyc
│ │ │ │ │ │ │ ├── terminal.cpython-312.pyc
│ │ │ │ │ │ │ └── terminal256.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ ├── bbcode.py
│ │ │ │ │ │ ├── groff.py
│ │ │ │ │ │ ├── html.py
│ │ │ │ │ │ ├── img.py
│ │ │ │ │ │ ├── irc.py
│ │ │ │ │ │ ├── latex.py
│ │ │ │ │ │ ├── other.py
│ │ │ │ │ │ ├── pangomarkup.py
│ │ │ │ │ │ ├── rtf.py
│ │ │ │ │ │ ├── svg.py
│ │ │ │ │ │ ├── terminal.py
│ │ │ │ │ │ └── terminal256.py
│ │ │ │ │ ├── lexer.py
│ │ │ │ │ ├── lexers
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ └── python.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ └── python.py
│ │ │ │ │ ├── modeline.py
│ │ │ │ │ ├── plugin.py
│ │ │ │ │ ├── regexopt.py
│ │ │ │ │ ├── scanner.py
│ │ │ │ │ ├── sphinxext.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styles
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── _mapping.cpython-312.pyc
│ │ │ │ │ │ └── _mapping.py
│ │ │ │ │ ├── token.py
│ │ │ │ │ ├── unistring.py
│ │ │ │ │ └── util.py
│ │ │ │ ├── pyproject_hooks
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ └── _impl.cpython-312.pyc
│ │ │ │ │ ├── _compat.py
│ │ │ │ │ ├── _impl.py
│ │ │ │ │ └── _in_process
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── _in_process.cpython-312.pyc
│ │ │ │ │ └── _in_process.py
│ │ │ │ ├── requests
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ │ ├── __version__.py
│ │ │ │ │ ├── _internal_utils.py
│ │ │ │ │ ├── adapters.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── certs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── cookies.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── hooks.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ ├── packages.py
│ │ │ │ │ ├── sessions.py
│ │ │ │ │ ├── status_codes.py
│ │ │ │ │ ├── structures.py
│ │ │ │ │ └── utils.py
│ │ │ │ ├── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── providers.cpython-312.pyc
│ │ │ │ │ │ ├── reporters.cpython-312.pyc
│ │ │ │ │ │ ├── resolvers.cpython-312.pyc
│ │ │ │ │ │ └── structs.cpython-312.pyc
│ │ │ │ │ ├── compat
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── collections_abc.cpython-312.pyc
│ │ │ │ │ │ └── collections_abc.py
│ │ │ │ │ ├── providers.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── reporters.py
│ │ │ │ │ ├── resolvers.py
│ │ │ │ │ └── structs.py
│ │ │ │ ├── rich
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── _cell_widths.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_codes.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_replace.cpython-312.pyc
│ │ │ │ │ │ ├── _export_format.cpython-312.pyc
│ │ │ │ │ │ ├── _extension.cpython-312.pyc
│ │ │ │ │ │ ├── _fileno.cpython-312.pyc
│ │ │ │ │ │ ├── _inspect.cpython-312.pyc
│ │ │ │ │ │ ├── _log_render.cpython-312.pyc
│ │ │ │ │ │ ├── _loop.cpython-312.pyc
│ │ │ │ │ │ ├── _null_file.cpython-312.pyc
│ │ │ │ │ │ ├── _palettes.cpython-312.pyc
│ │ │ │ │ │ ├── _pick.cpython-312.pyc
│ │ │ │ │ │ ├── _ratio.cpython-312.pyc
│ │ │ │ │ │ ├── _spinners.cpython-312.pyc
│ │ │ │ │ │ ├── _stack.cpython-312.pyc
│ │ │ │ │ │ ├── _timer.cpython-312.pyc
│ │ │ │ │ │ ├── _win32_console.cpython-312.pyc
│ │ │ │ │ │ ├── _windows_renderer.cpython-312.pyc
│ │ │ │ │ │ ├── _windows.cpython-312.pyc
│ │ │ │ │ │ ├── _wrap.cpython-312.pyc
│ │ │ │ │ │ ├── abc.cpython-312.pyc
│ │ │ │ │ │ ├── align.cpython-312.pyc
│ │ │ │ │ │ ├── ansi.cpython-312.pyc
│ │ │ │ │ │ ├── bar.cpython-312.pyc
│ │ │ │ │ │ ├── box.cpython-312.pyc
│ │ │ │ │ │ ├── cells.cpython-312.pyc
│ │ │ │ │ │ ├── color_triplet.cpython-312.pyc
│ │ │ │ │ │ ├── color.cpython-312.pyc
│ │ │ │ │ │ ├── columns.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── constrain.cpython-312.pyc
│ │ │ │ │ │ ├── containers.cpython-312.pyc
│ │ │ │ │ │ ├── control.cpython-312.pyc
│ │ │ │ │ │ ├── default_styles.cpython-312.pyc
│ │ │ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ │ │ ├── emoji.cpython-312.pyc
│ │ │ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ │ │ ├── file_proxy.cpython-312.pyc
│ │ │ │ │ │ ├── filesize.cpython-312.pyc
│ │ │ │ │ │ ├── highlighter.cpython-312.pyc
│ │ │ │ │ │ ├── json.cpython-312.pyc
│ │ │ │ │ │ ├── jupyter.cpython-312.pyc
│ │ │ │ │ │ ├── layout.cpython-312.pyc
│ │ │ │ │ │ ├── live_render.cpython-312.pyc
│ │ │ │ │ │ ├── live.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── markup.cpython-312.pyc
│ │ │ │ │ │ ├── measure.cpython-312.pyc
│ │ │ │ │ │ ├── padding.cpython-312.pyc
│ │ │ │ │ │ ├── pager.cpython-312.pyc
│ │ │ │ │ │ ├── palette.cpython-312.pyc
│ │ │ │ │ │ ├── panel.cpython-312.pyc
│ │ │ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bar.cpython-312.pyc
│ │ │ │ │ │ ├── progress.cpython-312.pyc
│ │ │ │ │ │ ├── prompt.cpython-312.pyc
│ │ │ │ │ │ ├── protocol.cpython-312.pyc
│ │ │ │ │ │ ├── region.cpython-312.pyc
│ │ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ │ ├── rule.cpython-312.pyc
│ │ │ │ │ │ ├── scope.cpython-312.pyc
│ │ │ │ │ │ ├── screen.cpython-312.pyc
│ │ │ │ │ │ ├── segment.cpython-312.pyc
│ │ │ │ │ │ ├── spinner.cpython-312.pyc
│ │ │ │ │ │ ├── status.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── styled.cpython-312.pyc
│ │ │ │ │ │ ├── syntax.cpython-312.pyc
│ │ │ │ │ │ ├── table.cpython-312.pyc
│ │ │ │ │ │ ├── terminal_theme.cpython-312.pyc
│ │ │ │ │ │ ├── text.cpython-312.pyc
│ │ │ │ │ │ ├── theme.cpython-312.pyc
│ │ │ │ │ │ ├── themes.cpython-312.pyc
│ │ │ │ │ │ ├── traceback.cpython-312.pyc
│ │ │ │ │ │ └── tree.cpython-312.pyc
│ │ │ │ │ ├── _cell_widths.py
│ │ │ │ │ ├── _emoji_codes.py
│ │ │ │ │ ├── _emoji_replace.py
│ │ │ │ │ ├── _export_format.py
│ │ │ │ │ ├── _extension.py
│ │ │ │ │ ├── _fileno.py
│ │ │ │ │ ├── _inspect.py
│ │ │ │ │ ├── _log_render.py
│ │ │ │ │ ├── _loop.py
│ │ │ │ │ ├── _null_file.py
│ │ │ │ │ ├── _palettes.py
│ │ │ │ │ ├── _pick.py
│ │ │ │ │ ├── _ratio.py
│ │ │ │ │ ├── _spinners.py
│ │ │ │ │ ├── _stack.py
│ │ │ │ │ ├── _timer.py
│ │ │ │ │ ├── _win32_console.py
│ │ │ │ │ ├── _windows_renderer.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ ├── _wrap.py
│ │ │ │ │ ├── abc.py
│ │ │ │ │ ├── align.py
│ │ │ │ │ ├── ansi.py
│ │ │ │ │ ├── bar.py
│ │ │ │ │ ├── box.py
│ │ │ │ │ ├── cells.py
│ │ │ │ │ ├── color_triplet.py
│ │ │ │ │ ├── color.py
│ │ │ │ │ ├── columns.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── constrain.py
│ │ │ │ │ ├── containers.py
│ │ │ │ │ ├── control.py
│ │ │ │ │ ├── default_styles.py
│ │ │ │ │ ├── diagnose.py
│ │ │ │ │ ├── emoji.py
│ │ │ │ │ ├── errors.py
│ │ │ │ │ ├── file_proxy.py
│ │ │ │ │ ├── filesize.py
│ │ │ │ │ ├── highlighter.py
│ │ │ │ │ ├── json.py
│ │ │ │ │ ├── jupyter.py
│ │ │ │ │ ├── layout.py
│ │ │ │ │ ├── live_render.py
│ │ │ │ │ ├── live.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── markup.py
│ │ │ │ │ ├── measure.py
│ │ │ │ │ ├── padding.py
│ │ │ │ │ ├── pager.py
│ │ │ │ │ ├── palette.py
│ │ │ │ │ ├── panel.py
│ │ │ │ │ ├── pretty.py
│ │ │ │ │ ├── progress_bar.py
│ │ │ │ │ ├── progress.py
│ │ │ │ │ ├── prompt.py
│ │ │ │ │ ├── protocol.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── region.py
│ │ │ │ │ ├── repr.py
│ │ │ │ │ ├── rule.py
│ │ │ │ │ ├── scope.py
│ │ │ │ │ ├── screen.py
│ │ │ │ │ ├── segment.py
│ │ │ │ │ ├── spinner.py
│ │ │ │ │ ├── status.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styled.py
│ │ │ │ │ ├── syntax.py
│ │ │ │ │ ├── table.py
│ │ │ │ │ ├── terminal_theme.py
│ │ │ │ │ ├── text.py
│ │ │ │ │ ├── theme.py
│ │ │ │ │ ├── themes.py
│ │ │ │ │ ├── traceback.py
│ │ │ │ │ └── tree.py
│ │ │ │ ├── tomli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _re.cpython-312.pyc
│ │ │ │ │ │ └── _types.cpython-312.pyc
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _re.py
│ │ │ │ │ ├── _types.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── truststore
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _api.cpython-312.pyc
│ │ │ │ │ │ ├── _macos.cpython-312.pyc
│ │ │ │ │ │ ├── _openssl.cpython-312.pyc
│ │ │ │ │ │ ├── _ssl_constants.cpython-312.pyc
│ │ │ │ │ │ └── _windows.cpython-312.pyc
│ │ │ │ │ ├── _api.py
│ │ │ │ │ ├── _macos.py
│ │ │ │ │ ├── _openssl.py
│ │ │ │ │ ├── _ssl_constants.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── typing_extensions.py
│ │ │ │ ├── urllib3
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── _collections.py
│ │ │ │ │ ├── _version.py
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── connectionpool.py
│ │ │ │ │ ├── contrib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _appengine_environ.cpython-312.pyc
│ │ │ │ │ │ │ ├── appengine.cpython-312.pyc
│ │ │ │ │ │ │ ├── ntlmpool.cpython-312.pyc
│ │ │ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ │ │ ├── securetransport.cpython-312.pyc
│ │ │ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ │ │ ├── _appengine_environ.py
│ │ │ │ │ │ ├── _securetransport
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── bindings.cpython-312.pyc
│ │ │ │ │ │ │ │ └── low_level.cpython-312.pyc
│ │ │ │ │ │ │ ├── bindings.py
│ │ │ │ │ │ │ └── low_level.py
│ │ │ │ │ │ ├── appengine.py
│ │ │ │ │ │ ├── ntlmpool.py
│ │ │ │ │ │ ├── pyopenssl.py
│ │ │ │ │ │ ├── securetransport.py
│ │ │ │ │ │ └── socks.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── fields.py
│ │ │ │ │ ├── filepost.py
│ │ │ │ │ ├── packages
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── six.cpython-312.pyc
│ │ │ │ │ │ ├── backports
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── makefile.cpython-312.pyc
│ │ │ │ │ │ │ │ └── weakref_finalize.cpython-312.pyc
│ │ │ │ │ │ │ ├── makefile.py
│ │ │ │ │ │ │ └── weakref_finalize.py
│ │ │ │ │ │ └── six.py
│ │ │ │ │ ├── poolmanager.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ └── util
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ │ │ ├── queue.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ │ │ └── wait.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── proxy.py
│ │ │ │ │ ├── queue.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── ssl_.py
│ │ │ │ │ ├── ssl_match_hostname.py
│ │ │ │ │ ├── ssltransport.py
│ │ │ │ │ ├── timeout.py
│ │ │ │ │ ├── url.py
│ │ │ │ │ └── wait.py
│ │ │ │ └── vendor.txt
│ │ │ └── py.typed
│ │ ├── pip-24.2.dist-info
│ │ │ ├── AUTHORS.txt
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── requests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── __version__.py
│ │ │ ├── _internal_utils.py
│ │ │ ├── adapters.py
│ │ │ ├── api.py
│ │ │ ├── auth.py
│ │ │ ├── certs.py
│ │ │ ├── compat.py
│ │ │ ├── cookies.py
│ │ │ ├── exceptions.py
│ │ │ ├── help.py
│ │ │ ├── hooks.py
│ │ │ ├── models.py
│ │ │ ├── packages.py
│ │ │ ├── sessions.py
│ │ │ ├── status_codes.py
│ │ │ ├── structures.py
│ │ │ └── utils.py
│ │ ├── requests-2.32.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── soupsieve
│ │ │ ├── __init__.py
│ │ │ ├── __meta__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __meta__.cpython-312.pyc
│ │ │ │ ├── css_match.cpython-312.pyc
│ │ │ │ ├── css_parser.cpython-312.pyc
│ │ │ │ ├── css_types.cpython-312.pyc
│ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ └── util.cpython-312.pyc
│ │ │ ├── css_match.py
│ │ │ ├── css_parser.py
│ │ │ ├── css_types.py
│ │ │ ├── pretty.py
│ │ │ ├── py.typed
│ │ │ └── util.py
│ │ ├── soupsieve-2.6.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── urllib3
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _base_connection.cpython-312.pyc
│ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ ├── _request_methods.cpython-312.pyc
│ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ └── response.cpython-312.pyc
│ │ │ ├── _base_connection.py
│ │ │ ├── _collections.py
│ │ │ ├── _request_methods.py
│ │ │ ├── _version.py
│ │ │ ├── connection.py
│ │ │ ├── connectionpool.py
│ │ │ ├── contrib
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ ├── emscripten
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── fetch.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── emscripten_fetch_worker.js
│ │ │ │ │ ├── fetch.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ └── response.py
│ │ │ │ ├── pyopenssl.py
│ │ │ │ └── socks.py
│ │ │ ├── exceptions.py
│ │ │ ├── fields.py
│ │ │ ├── filepost.py
│ │ │ ├── http2
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ └── probe.cpython-312.pyc
│ │ │ │ ├── connection.py
│ │ │ │ └── probe.py
│ │ │ ├── poolmanager.py
│ │ │ ├── py.typed
│ │ │ ├── response.py
│ │ │ └── util
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ └── wait.cpython-312.pyc
│ │ │ ├── connection.py
│ │ │ ├── proxy.py
│ │ │ ├── request.py
│ │ │ ├── response.py
│ │ │ ├── retry.py
│ │ │ ├── ssl_.py
│ │ │ ├── ssl_match_hostname.py
│ │ │ ├── ssltransport.py
│ │ │ ├── timeout.py
│ │ │ ├── url.py
│ │ │ ├── util.py
│ │ │ └── wait.py
│ │ ├── urllib3-2.2.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── useragent
│ │ │ ├── __init__.py
│ │ │ ├── __init__.pyc
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── resources
│ │ │ │ └── user_agent_data.json
│ │ │ └── test
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── test_additional_os.json
│ │ │ ├── test_browser.json
│ │ │ ├── test_device.json
│ │ │ ├── test_firefox.json
│ │ │ ├── test_os.json
│ │ │ └── test_pgts_browser.json
│ │ ├── useragent-0.1.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── werkzeug
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _internal.cpython-312.pyc
│ │ │ │ ├── _reloader.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formparser.cpython-312.pyc
│ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ ├── local.cpython-312.pyc
│ │ │ │ ├── security.cpython-312.pyc
│ │ │ │ ├── serving.cpython-312.pyc
│ │ │ │ ├── test.cpython-312.pyc
│ │ │ │ ├── testapp.cpython-312.pyc
│ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ ├── user_agent.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── wsgi.cpython-312.pyc
│ │ │ ├── _internal.py
│ │ │ ├── _reloader.py
│ │ │ ├── datastructures
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── accept.cpython-312.pyc
│ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ ├── cache_control.cpython-312.pyc
│ │ │ │ │ ├── csp.cpython-312.pyc
│ │ │ │ │ ├── etag.cpython-312.pyc
│ │ │ │ │ ├── file_storage.cpython-312.pyc
│ │ │ │ │ ├── headers.cpython-312.pyc
│ │ │ │ │ ├── mixins.cpython-312.pyc
│ │ │ │ │ ├── range.cpython-312.pyc
│ │ │ │ │ └── structures.cpython-312.pyc
│ │ │ │ ├── accept.py
│ │ │ │ ├── accept.pyi
│ │ │ │ ├── auth.py
│ │ │ │ ├── cache_control.py
│ │ │ │ ├── cache_control.pyi
│ │ │ │ ├── csp.py
│ │ │ │ ├── csp.pyi
│ │ │ │ ├── etag.py
│ │ │ │ ├── etag.pyi
│ │ │ │ ├── file_storage.py
│ │ │ │ ├── file_storage.pyi
│ │ │ │ ├── headers.py
│ │ │ │ ├── headers.pyi
│ │ │ │ ├── mixins.py
│ │ │ │ ├── mixins.pyi
│ │ │ │ ├── range.py
│ │ │ │ ├── range.pyi
│ │ │ │ ├── structures.py
│ │ │ │ └── structures.pyi
│ │ │ ├── debug
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ └── tbtools.cpython-312.pyc
│ │ │ │ ├── console.py
│ │ │ │ ├── repr.py
│ │ │ │ ├── shared
│ │ │ │ │ ├── console.png
│ │ │ │ │ ├── debugger.js
│ │ │ │ │ ├── ICON_LICENSE.md
│ │ │ │ │ ├── less.png
│ │ │ │ │ ├── more.png
│ │ │ │ │ └── style.css
│ │ │ │ └── tbtools.py
│ │ │ ├── exceptions.py
│ │ │ ├── formparser.py
│ │ │ ├── http.py
│ │ │ ├── local.py
│ │ │ ├── middleware
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── dispatcher.cpython-312.pyc
│ │ │ │ │ ├── http_proxy.cpython-312.pyc
│ │ │ │ │ ├── lint.cpython-312.pyc
│ │ │ │ │ ├── profiler.cpython-312.pyc
│ │ │ │ │ ├── proxy_fix.cpython-312.pyc
│ │ │ │ │ └── shared_data.cpython-312.pyc
│ │ │ │ ├── dispatcher.py
│ │ │ │ ├── http_proxy.py
│ │ │ │ ├── lint.py
│ │ │ │ ├── profiler.py
│ │ │ │ ├── proxy_fix.py
│ │ │ │ └── shared_data.py
│ │ │ ├── py.typed
│ │ │ ├── routing
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── converters.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── map.cpython-312.pyc
│ │ │ │ │ ├── matcher.cpython-312.pyc
│ │ │ │ │ └── rules.cpython-312.pyc
│ │ │ │ ├── converters.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── map.py
│ │ │ │ ├── matcher.py
│ │ │ │ └── rules.py
│ │ │ ├── sansio
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ │ ├── multipart.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ ├── http.py
│ │ │ │ ├── multipart.py
│ │ │ │ ├── request.py
│ │ │ │ ├── response.py
│ │ │ │ └── utils.py
│ │ │ ├── security.py
│ │ │ ├── serving.py
│ │ │ ├── test.py
│ │ │ ├── testapp.py
│ │ │ ├── urls.py
│ │ │ ├── user_agent.py
│ │ │ ├── utils.py
│ │ │ ├── wrappers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ ├── request.py
│ │ │ │ └── response.py
│ │ │ └── wsgi.py
│ │ └── werkzeug-3.0.4.dist-info
│ │ ├── INSTALLER
│ │ ├── LICENSE.txt
│ │ ├── METADATA
│ │ ├── RECORD
│ │ └── WHEEL
│ ├── pyvenv.cfg
│ ├── static
│ │ └── styles.css
│ ├── templates
│ │ └── index.html
│ └── test.py
├── cline_config.json
├── mcp_server.py
├── README.md
├── search_results.json
├── settings.json
└── test_files
├── text1.txt
└── text2.txt
```
# Files
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/rich/_win32_console.py:
--------------------------------------------------------------------------------
```python
1 | """Light wrapper around the Win32 Console API - this module should only be imported on Windows
2 |
3 | The API that this module wraps is documented at https://docs.microsoft.com/en-us/windows/console/console-functions
4 | """
5 | import ctypes
6 | import sys
7 | from typing import Any
8 |
9 | windll: Any = None
10 | if sys.platform == "win32":
11 | windll = ctypes.LibraryLoader(ctypes.WinDLL)
12 | else:
13 | raise ImportError(f"{__name__} can only be imported on Windows")
14 |
15 | import time
16 | from ctypes import Structure, byref, wintypes
17 | from typing import IO, NamedTuple, Type, cast
18 |
19 | from pip._vendor.rich.color import ColorSystem
20 | from pip._vendor.rich.style import Style
21 |
22 | STDOUT = -11
23 | ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
24 |
25 | COORD = wintypes._COORD
26 |
27 |
28 | class LegacyWindowsError(Exception):
29 | pass
30 |
31 |
32 | class WindowsCoordinates(NamedTuple):
33 | """Coordinates in the Windows Console API are (y, x), not (x, y).
34 | This class is intended to prevent that confusion.
35 | Rows and columns are indexed from 0.
36 | This class can be used in place of wintypes._COORD in arguments and argtypes.
37 | """
38 |
39 | row: int
40 | col: int
41 |
42 | @classmethod
43 | def from_param(cls, value: "WindowsCoordinates") -> COORD:
44 | """Converts a WindowsCoordinates into a wintypes _COORD structure.
45 | This classmethod is internally called by ctypes to perform the conversion.
46 |
47 | Args:
48 | value (WindowsCoordinates): The input coordinates to convert.
49 |
50 | Returns:
51 | wintypes._COORD: The converted coordinates struct.
52 | """
53 | return COORD(value.col, value.row)
54 |
55 |
56 | class CONSOLE_SCREEN_BUFFER_INFO(Structure):
57 | _fields_ = [
58 | ("dwSize", COORD),
59 | ("dwCursorPosition", COORD),
60 | ("wAttributes", wintypes.WORD),
61 | ("srWindow", wintypes.SMALL_RECT),
62 | ("dwMaximumWindowSize", COORD),
63 | ]
64 |
65 |
66 | class CONSOLE_CURSOR_INFO(ctypes.Structure):
67 | _fields_ = [("dwSize", wintypes.DWORD), ("bVisible", wintypes.BOOL)]
68 |
69 |
70 | _GetStdHandle = windll.kernel32.GetStdHandle
71 | _GetStdHandle.argtypes = [
72 | wintypes.DWORD,
73 | ]
74 | _GetStdHandle.restype = wintypes.HANDLE
75 |
76 |
77 | def GetStdHandle(handle: int = STDOUT) -> wintypes.HANDLE:
78 | """Retrieves a handle to the specified standard device (standard input, standard output, or standard error).
79 |
80 | Args:
81 | handle (int): Integer identifier for the handle. Defaults to -11 (stdout).
82 |
83 | Returns:
84 | wintypes.HANDLE: The handle
85 | """
86 | return cast(wintypes.HANDLE, _GetStdHandle(handle))
87 |
88 |
89 | _GetConsoleMode = windll.kernel32.GetConsoleMode
90 | _GetConsoleMode.argtypes = [wintypes.HANDLE, wintypes.LPDWORD]
91 | _GetConsoleMode.restype = wintypes.BOOL
92 |
93 |
94 | def GetConsoleMode(std_handle: wintypes.HANDLE) -> int:
95 | """Retrieves the current input mode of a console's input buffer
96 | or the current output mode of a console screen buffer.
97 |
98 | Args:
99 | std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
100 |
101 | Raises:
102 | LegacyWindowsError: If any error occurs while calling the Windows console API.
103 |
104 | Returns:
105 | int: Value representing the current console mode as documented at
106 | https://docs.microsoft.com/en-us/windows/console/getconsolemode#parameters
107 | """
108 |
109 | console_mode = wintypes.DWORD()
110 | success = bool(_GetConsoleMode(std_handle, console_mode))
111 | if not success:
112 | raise LegacyWindowsError("Unable to get legacy Windows Console Mode")
113 | return console_mode.value
114 |
115 |
116 | _FillConsoleOutputCharacterW = windll.kernel32.FillConsoleOutputCharacterW
117 | _FillConsoleOutputCharacterW.argtypes = [
118 | wintypes.HANDLE,
119 | ctypes.c_char,
120 | wintypes.DWORD,
121 | cast(Type[COORD], WindowsCoordinates),
122 | ctypes.POINTER(wintypes.DWORD),
123 | ]
124 | _FillConsoleOutputCharacterW.restype = wintypes.BOOL
125 |
126 |
127 | def FillConsoleOutputCharacter(
128 | std_handle: wintypes.HANDLE,
129 | char: str,
130 | length: int,
131 | start: WindowsCoordinates,
132 | ) -> int:
133 | """Writes a character to the console screen buffer a specified number of times, beginning at the specified coordinates.
134 |
135 | Args:
136 | std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
137 | char (str): The character to write. Must be a string of length 1.
138 | length (int): The number of times to write the character.
139 | start (WindowsCoordinates): The coordinates to start writing at.
140 |
141 | Returns:
142 | int: The number of characters written.
143 | """
144 | character = ctypes.c_char(char.encode())
145 | num_characters = wintypes.DWORD(length)
146 | num_written = wintypes.DWORD(0)
147 | _FillConsoleOutputCharacterW(
148 | std_handle,
149 | character,
150 | num_characters,
151 | start,
152 | byref(num_written),
153 | )
154 | return num_written.value
155 |
156 |
157 | _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute
158 | _FillConsoleOutputAttribute.argtypes = [
159 | wintypes.HANDLE,
160 | wintypes.WORD,
161 | wintypes.DWORD,
162 | cast(Type[COORD], WindowsCoordinates),
163 | ctypes.POINTER(wintypes.DWORD),
164 | ]
165 | _FillConsoleOutputAttribute.restype = wintypes.BOOL
166 |
167 |
168 | def FillConsoleOutputAttribute(
169 | std_handle: wintypes.HANDLE,
170 | attributes: int,
171 | length: int,
172 | start: WindowsCoordinates,
173 | ) -> int:
174 | """Sets the character attributes for a specified number of character cells,
175 | beginning at the specified coordinates in a screen buffer.
176 |
177 | Args:
178 | std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
179 | attributes (int): Integer value representing the foreground and background colours of the cells.
180 | length (int): The number of cells to set the output attribute of.
181 | start (WindowsCoordinates): The coordinates of the first cell whose attributes are to be set.
182 |
183 | Returns:
184 | int: The number of cells whose attributes were actually set.
185 | """
186 | num_cells = wintypes.DWORD(length)
187 | style_attrs = wintypes.WORD(attributes)
188 | num_written = wintypes.DWORD(0)
189 | _FillConsoleOutputAttribute(
190 | std_handle, style_attrs, num_cells, start, byref(num_written)
191 | )
192 | return num_written.value
193 |
194 |
195 | _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute
196 | _SetConsoleTextAttribute.argtypes = [
197 | wintypes.HANDLE,
198 | wintypes.WORD,
199 | ]
200 | _SetConsoleTextAttribute.restype = wintypes.BOOL
201 |
202 |
203 | def SetConsoleTextAttribute(
204 | std_handle: wintypes.HANDLE, attributes: wintypes.WORD
205 | ) -> bool:
206 | """Set the colour attributes for all text written after this function is called.
207 |
208 | Args:
209 | std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
210 | attributes (int): Integer value representing the foreground and background colours.
211 |
212 |
213 | Returns:
214 | bool: True if the attribute was set successfully, otherwise False.
215 | """
216 | return bool(_SetConsoleTextAttribute(std_handle, attributes))
217 |
218 |
219 | _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo
220 | _GetConsoleScreenBufferInfo.argtypes = [
221 | wintypes.HANDLE,
222 | ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO),
223 | ]
224 | _GetConsoleScreenBufferInfo.restype = wintypes.BOOL
225 |
226 |
227 | def GetConsoleScreenBufferInfo(
228 | std_handle: wintypes.HANDLE,
229 | ) -> CONSOLE_SCREEN_BUFFER_INFO:
230 | """Retrieves information about the specified console screen buffer.
231 |
232 | Args:
233 | std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
234 |
235 | Returns:
236 | CONSOLE_SCREEN_BUFFER_INFO: A CONSOLE_SCREEN_BUFFER_INFO ctype struct contain information about
237 | screen size, cursor position, colour attributes, and more."""
238 | console_screen_buffer_info = CONSOLE_SCREEN_BUFFER_INFO()
239 | _GetConsoleScreenBufferInfo(std_handle, byref(console_screen_buffer_info))
240 | return console_screen_buffer_info
241 |
242 |
243 | _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition
244 | _SetConsoleCursorPosition.argtypes = [
245 | wintypes.HANDLE,
246 | cast(Type[COORD], WindowsCoordinates),
247 | ]
248 | _SetConsoleCursorPosition.restype = wintypes.BOOL
249 |
250 |
251 | def SetConsoleCursorPosition(
252 | std_handle: wintypes.HANDLE, coords: WindowsCoordinates
253 | ) -> bool:
254 | """Set the position of the cursor in the console screen
255 |
256 | Args:
257 | std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
258 | coords (WindowsCoordinates): The coordinates to move the cursor to.
259 |
260 | Returns:
261 | bool: True if the function succeeds, otherwise False.
262 | """
263 | return bool(_SetConsoleCursorPosition(std_handle, coords))
264 |
265 |
266 | _GetConsoleCursorInfo = windll.kernel32.GetConsoleCursorInfo
267 | _GetConsoleCursorInfo.argtypes = [
268 | wintypes.HANDLE,
269 | ctypes.POINTER(CONSOLE_CURSOR_INFO),
270 | ]
271 | _GetConsoleCursorInfo.restype = wintypes.BOOL
272 |
273 |
274 | def GetConsoleCursorInfo(
275 | std_handle: wintypes.HANDLE, cursor_info: CONSOLE_CURSOR_INFO
276 | ) -> bool:
277 | """Get the cursor info - used to get cursor visibility and width
278 |
279 | Args:
280 | std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
281 | cursor_info (CONSOLE_CURSOR_INFO): CONSOLE_CURSOR_INFO ctype struct that receives information
282 | about the console's cursor.
283 |
284 | Returns:
285 | bool: True if the function succeeds, otherwise False.
286 | """
287 | return bool(_GetConsoleCursorInfo(std_handle, byref(cursor_info)))
288 |
289 |
290 | _SetConsoleCursorInfo = windll.kernel32.SetConsoleCursorInfo
291 | _SetConsoleCursorInfo.argtypes = [
292 | wintypes.HANDLE,
293 | ctypes.POINTER(CONSOLE_CURSOR_INFO),
294 | ]
295 | _SetConsoleCursorInfo.restype = wintypes.BOOL
296 |
297 |
298 | def SetConsoleCursorInfo(
299 | std_handle: wintypes.HANDLE, cursor_info: CONSOLE_CURSOR_INFO
300 | ) -> bool:
301 | """Set the cursor info - used for adjusting cursor visibility and width
302 |
303 | Args:
304 | std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
305 | cursor_info (CONSOLE_CURSOR_INFO): CONSOLE_CURSOR_INFO ctype struct containing the new cursor info.
306 |
307 | Returns:
308 | bool: True if the function succeeds, otherwise False.
309 | """
310 | return bool(_SetConsoleCursorInfo(std_handle, byref(cursor_info)))
311 |
312 |
313 | _SetConsoleTitle = windll.kernel32.SetConsoleTitleW
314 | _SetConsoleTitle.argtypes = [wintypes.LPCWSTR]
315 | _SetConsoleTitle.restype = wintypes.BOOL
316 |
317 |
318 | def SetConsoleTitle(title: str) -> bool:
319 | """Sets the title of the current console window
320 |
321 | Args:
322 | title (str): The new title of the console window.
323 |
324 | Returns:
325 | bool: True if the function succeeds, otherwise False.
326 | """
327 | return bool(_SetConsoleTitle(title))
328 |
329 |
330 | class LegacyWindowsTerm:
331 | """This class allows interaction with the legacy Windows Console API. It should only be used in the context
332 | of environments where virtual terminal processing is not available. However, if it is used in a Windows environment,
333 | the entire API should work.
334 |
335 | Args:
336 | file (IO[str]): The file which the Windows Console API HANDLE is retrieved from, defaults to sys.stdout.
337 | """
338 |
339 | BRIGHT_BIT = 8
340 |
341 | # Indices are ANSI color numbers, values are the corresponding Windows Console API color numbers
342 | ANSI_TO_WINDOWS = [
343 | 0, # black The Windows colours are defined in wincon.h as follows:
344 | 4, # red define FOREGROUND_BLUE 0x0001 -- 0000 0001
345 | 2, # green define FOREGROUND_GREEN 0x0002 -- 0000 0010
346 | 6, # yellow define FOREGROUND_RED 0x0004 -- 0000 0100
347 | 1, # blue define FOREGROUND_INTENSITY 0x0008 -- 0000 1000
348 | 5, # magenta define BACKGROUND_BLUE 0x0010 -- 0001 0000
349 | 3, # cyan define BACKGROUND_GREEN 0x0020 -- 0010 0000
350 | 7, # white define BACKGROUND_RED 0x0040 -- 0100 0000
351 | 8, # bright black (grey) define BACKGROUND_INTENSITY 0x0080 -- 1000 0000
352 | 12, # bright red
353 | 10, # bright green
354 | 14, # bright yellow
355 | 9, # bright blue
356 | 13, # bright magenta
357 | 11, # bright cyan
358 | 15, # bright white
359 | ]
360 |
361 | def __init__(self, file: "IO[str]") -> None:
362 | handle = GetStdHandle(STDOUT)
363 | self._handle = handle
364 | default_text = GetConsoleScreenBufferInfo(handle).wAttributes
365 | self._default_text = default_text
366 |
367 | self._default_fore = default_text & 7
368 | self._default_back = (default_text >> 4) & 7
369 | self._default_attrs = self._default_fore | (self._default_back << 4)
370 |
371 | self._file = file
372 | self.write = file.write
373 | self.flush = file.flush
374 |
375 | @property
376 | def cursor_position(self) -> WindowsCoordinates:
377 | """Returns the current position of the cursor (0-based)
378 |
379 | Returns:
380 | WindowsCoordinates: The current cursor position.
381 | """
382 | coord: COORD = GetConsoleScreenBufferInfo(self._handle).dwCursorPosition
383 | return WindowsCoordinates(row=cast(int, coord.Y), col=cast(int, coord.X))
384 |
385 | @property
386 | def screen_size(self) -> WindowsCoordinates:
387 | """Returns the current size of the console screen buffer, in character columns and rows
388 |
389 | Returns:
390 | WindowsCoordinates: The width and height of the screen as WindowsCoordinates.
391 | """
392 | screen_size: COORD = GetConsoleScreenBufferInfo(self._handle).dwSize
393 | return WindowsCoordinates(
394 | row=cast(int, screen_size.Y), col=cast(int, screen_size.X)
395 | )
396 |
397 | def write_text(self, text: str) -> None:
398 | """Write text directly to the terminal without any modification of styles
399 |
400 | Args:
401 | text (str): The text to write to the console
402 | """
403 | self.write(text)
404 | self.flush()
405 |
406 | def write_styled(self, text: str, style: Style) -> None:
407 | """Write styled text to the terminal.
408 |
409 | Args:
410 | text (str): The text to write
411 | style (Style): The style of the text
412 | """
413 | color = style.color
414 | bgcolor = style.bgcolor
415 | if style.reverse:
416 | color, bgcolor = bgcolor, color
417 |
418 | if color:
419 | fore = color.downgrade(ColorSystem.WINDOWS).number
420 | fore = fore if fore is not None else 7 # Default to ANSI 7: White
421 | if style.bold:
422 | fore = fore | self.BRIGHT_BIT
423 | if style.dim:
424 | fore = fore & ~self.BRIGHT_BIT
425 | fore = self.ANSI_TO_WINDOWS[fore]
426 | else:
427 | fore = self._default_fore
428 |
429 | if bgcolor:
430 | back = bgcolor.downgrade(ColorSystem.WINDOWS).number
431 | back = back if back is not None else 0 # Default to ANSI 0: Black
432 | back = self.ANSI_TO_WINDOWS[back]
433 | else:
434 | back = self._default_back
435 |
436 | assert fore is not None
437 | assert back is not None
438 |
439 | SetConsoleTextAttribute(
440 | self._handle, attributes=ctypes.c_ushort(fore | (back << 4))
441 | )
442 | self.write_text(text)
443 | SetConsoleTextAttribute(self._handle, attributes=self._default_text)
444 |
445 | def move_cursor_to(self, new_position: WindowsCoordinates) -> None:
446 | """Set the position of the cursor
447 |
448 | Args:
449 | new_position (WindowsCoordinates): The WindowsCoordinates representing the new position of the cursor.
450 | """
451 | if new_position.col < 0 or new_position.row < 0:
452 | return
453 | SetConsoleCursorPosition(self._handle, coords=new_position)
454 |
455 | def erase_line(self) -> None:
456 | """Erase all content on the line the cursor is currently located at"""
457 | screen_size = self.screen_size
458 | cursor_position = self.cursor_position
459 | cells_to_erase = screen_size.col
460 | start_coordinates = WindowsCoordinates(row=cursor_position.row, col=0)
461 | FillConsoleOutputCharacter(
462 | self._handle, " ", length=cells_to_erase, start=start_coordinates
463 | )
464 | FillConsoleOutputAttribute(
465 | self._handle,
466 | self._default_attrs,
467 | length=cells_to_erase,
468 | start=start_coordinates,
469 | )
470 |
471 | def erase_end_of_line(self) -> None:
472 | """Erase all content from the cursor position to the end of that line"""
473 | cursor_position = self.cursor_position
474 | cells_to_erase = self.screen_size.col - cursor_position.col
475 | FillConsoleOutputCharacter(
476 | self._handle, " ", length=cells_to_erase, start=cursor_position
477 | )
478 | FillConsoleOutputAttribute(
479 | self._handle,
480 | self._default_attrs,
481 | length=cells_to_erase,
482 | start=cursor_position,
483 | )
484 |
485 | def erase_start_of_line(self) -> None:
486 | """Erase all content from the cursor position to the start of that line"""
487 | row, col = self.cursor_position
488 | start = WindowsCoordinates(row, 0)
489 | FillConsoleOutputCharacter(self._handle, " ", length=col, start=start)
490 | FillConsoleOutputAttribute(
491 | self._handle, self._default_attrs, length=col, start=start
492 | )
493 |
494 | def move_cursor_up(self) -> None:
495 | """Move the cursor up a single cell"""
496 | cursor_position = self.cursor_position
497 | SetConsoleCursorPosition(
498 | self._handle,
499 | coords=WindowsCoordinates(
500 | row=cursor_position.row - 1, col=cursor_position.col
501 | ),
502 | )
503 |
504 | def move_cursor_down(self) -> None:
505 | """Move the cursor down a single cell"""
506 | cursor_position = self.cursor_position
507 | SetConsoleCursorPosition(
508 | self._handle,
509 | coords=WindowsCoordinates(
510 | row=cursor_position.row + 1,
511 | col=cursor_position.col,
512 | ),
513 | )
514 |
515 | def move_cursor_forward(self) -> None:
516 | """Move the cursor forward a single cell. Wrap to the next line if required."""
517 | row, col = self.cursor_position
518 | if col == self.screen_size.col - 1:
519 | row += 1
520 | col = 0
521 | else:
522 | col += 1
523 | SetConsoleCursorPosition(
524 | self._handle, coords=WindowsCoordinates(row=row, col=col)
525 | )
526 |
527 | def move_cursor_to_column(self, column: int) -> None:
528 | """Move cursor to the column specified by the zero-based column index, staying on the same row
529 |
530 | Args:
531 | column (int): The zero-based column index to move the cursor to.
532 | """
533 | row, _ = self.cursor_position
534 | SetConsoleCursorPosition(self._handle, coords=WindowsCoordinates(row, column))
535 |
536 | def move_cursor_backward(self) -> None:
537 | """Move the cursor backward a single cell. Wrap to the previous line if required."""
538 | row, col = self.cursor_position
539 | if col == 0:
540 | row -= 1
541 | col = self.screen_size.col - 1
542 | else:
543 | col -= 1
544 | SetConsoleCursorPosition(
545 | self._handle, coords=WindowsCoordinates(row=row, col=col)
546 | )
547 |
548 | def hide_cursor(self) -> None:
549 | """Hide the cursor"""
550 | current_cursor_size = self._get_cursor_size()
551 | invisible_cursor = CONSOLE_CURSOR_INFO(dwSize=current_cursor_size, bVisible=0)
552 | SetConsoleCursorInfo(self._handle, cursor_info=invisible_cursor)
553 |
554 | def show_cursor(self) -> None:
555 | """Show the cursor"""
556 | current_cursor_size = self._get_cursor_size()
557 | visible_cursor = CONSOLE_CURSOR_INFO(dwSize=current_cursor_size, bVisible=1)
558 | SetConsoleCursorInfo(self._handle, cursor_info=visible_cursor)
559 |
560 | def set_title(self, title: str) -> None:
561 | """Set the title of the terminal window
562 |
563 | Args:
564 | title (str): The new title of the console window
565 | """
566 | assert len(title) < 255, "Console title must be less than 255 characters"
567 | SetConsoleTitle(title)
568 |
569 | def _get_cursor_size(self) -> int:
570 | """Get the percentage of the character cell that is filled by the cursor"""
571 | cursor_info = CONSOLE_CURSOR_INFO()
572 | GetConsoleCursorInfo(self._handle, cursor_info=cursor_info)
573 | return int(cursor_info.dwSize)
574 |
575 |
576 | if __name__ == "__main__":
577 | handle = GetStdHandle()
578 |
579 | from pip._vendor.rich.console import Console
580 |
581 | console = Console()
582 |
583 | term = LegacyWindowsTerm(sys.stdout)
584 | term.set_title("Win32 Console Examples")
585 |
586 | style = Style(color="black", bgcolor="red")
587 |
588 | heading = Style.parse("black on green")
589 |
590 | # Check colour output
591 | console.rule("Checking colour output")
592 | console.print("[on red]on red!")
593 | console.print("[blue]blue!")
594 | console.print("[yellow]yellow!")
595 | console.print("[bold yellow]bold yellow!")
596 | console.print("[bright_yellow]bright_yellow!")
597 | console.print("[dim bright_yellow]dim bright_yellow!")
598 | console.print("[italic cyan]italic cyan!")
599 | console.print("[bold white on blue]bold white on blue!")
600 | console.print("[reverse bold white on blue]reverse bold white on blue!")
601 | console.print("[bold black on cyan]bold black on cyan!")
602 | console.print("[black on green]black on green!")
603 | console.print("[blue on green]blue on green!")
604 | console.print("[white on black]white on black!")
605 | console.print("[black on white]black on white!")
606 | console.print("[#1BB152 on #DA812D]#1BB152 on #DA812D!")
607 |
608 | # Check cursor movement
609 | console.rule("Checking cursor movement")
610 | console.print()
611 | term.move_cursor_backward()
612 | term.move_cursor_backward()
613 | term.write_text("went back and wrapped to prev line")
614 | time.sleep(1)
615 | term.move_cursor_up()
616 | term.write_text("we go up")
617 | time.sleep(1)
618 | term.move_cursor_down()
619 | term.write_text("and down")
620 | time.sleep(1)
621 | term.move_cursor_up()
622 | term.move_cursor_backward()
623 | term.move_cursor_backward()
624 | term.write_text("we went up and back 2")
625 | time.sleep(1)
626 | term.move_cursor_down()
627 | term.move_cursor_backward()
628 | term.move_cursor_backward()
629 | term.write_text("we went down and back 2")
630 | time.sleep(1)
631 |
632 | # Check erasing of lines
633 | term.hide_cursor()
634 | console.print()
635 | console.rule("Checking line erasing")
636 | console.print("\n...Deleting to the start of the line...")
637 | term.write_text("The red arrow shows the cursor location, and direction of erase")
638 | time.sleep(1)
639 | term.move_cursor_to_column(16)
640 | term.write_styled("<", Style.parse("black on red"))
641 | term.move_cursor_backward()
642 | time.sleep(1)
643 | term.erase_start_of_line()
644 | time.sleep(1)
645 |
646 | console.print("\n\n...And to the end of the line...")
647 | term.write_text("The red arrow shows the cursor location, and direction of erase")
648 | time.sleep(1)
649 |
650 | term.move_cursor_to_column(16)
651 | term.write_styled(">", Style.parse("black on red"))
652 | time.sleep(1)
653 | term.erase_end_of_line()
654 | time.sleep(1)
655 |
656 | console.print("\n\n...Now the whole line will be erased...")
657 | term.write_styled("I'm going to disappear!", style=Style.parse("black on cyan"))
658 | time.sleep(1)
659 | term.erase_line()
660 |
661 | term.show_cursor()
662 | print("\n")
663 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/urllib3/poolmanager.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import functools
4 | import logging
5 | import typing
6 | import warnings
7 | from types import TracebackType
8 | from urllib.parse import urljoin
9 |
10 | from ._collections import HTTPHeaderDict, RecentlyUsedContainer
11 | from ._request_methods import RequestMethods
12 | from .connection import ProxyConfig
13 | from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme
14 | from .exceptions import (
15 | LocationValueError,
16 | MaxRetryError,
17 | ProxySchemeUnknown,
18 | URLSchemeUnknown,
19 | )
20 | from .response import BaseHTTPResponse
21 | from .util.connection import _TYPE_SOCKET_OPTIONS
22 | from .util.proxy import connection_requires_http_tunnel
23 | from .util.retry import Retry
24 | from .util.timeout import Timeout
25 | from .util.url import Url, parse_url
26 |
27 | if typing.TYPE_CHECKING:
28 | import ssl
29 |
30 | from typing_extensions import Self
31 |
32 | __all__ = ["PoolManager", "ProxyManager", "proxy_from_url"]
33 |
34 |
35 | log = logging.getLogger(__name__)
36 |
37 | SSL_KEYWORDS = (
38 | "key_file",
39 | "cert_file",
40 | "cert_reqs",
41 | "ca_certs",
42 | "ca_cert_data",
43 | "ssl_version",
44 | "ssl_minimum_version",
45 | "ssl_maximum_version",
46 | "ca_cert_dir",
47 | "ssl_context",
48 | "key_password",
49 | "server_hostname",
50 | )
51 | # Default value for `blocksize` - a new parameter introduced to
52 | # http.client.HTTPConnection & http.client.HTTPSConnection in Python 3.7
53 | _DEFAULT_BLOCKSIZE = 16384
54 |
55 |
56 | class PoolKey(typing.NamedTuple):
57 | """
58 | All known keyword arguments that could be provided to the pool manager, its
59 | pools, or the underlying connections.
60 |
61 | All custom key schemes should include the fields in this key at a minimum.
62 | """
63 |
64 | key_scheme: str
65 | key_host: str
66 | key_port: int | None
67 | key_timeout: Timeout | float | int | None
68 | key_retries: Retry | bool | int | None
69 | key_block: bool | None
70 | key_source_address: tuple[str, int] | None
71 | key_key_file: str | None
72 | key_key_password: str | None
73 | key_cert_file: str | None
74 | key_cert_reqs: str | None
75 | key_ca_certs: str | None
76 | key_ca_cert_data: str | bytes | None
77 | key_ssl_version: int | str | None
78 | key_ssl_minimum_version: ssl.TLSVersion | None
79 | key_ssl_maximum_version: ssl.TLSVersion | None
80 | key_ca_cert_dir: str | None
81 | key_ssl_context: ssl.SSLContext | None
82 | key_maxsize: int | None
83 | key_headers: frozenset[tuple[str, str]] | None
84 | key__proxy: Url | None
85 | key__proxy_headers: frozenset[tuple[str, str]] | None
86 | key__proxy_config: ProxyConfig | None
87 | key_socket_options: _TYPE_SOCKET_OPTIONS | None
88 | key__socks_options: frozenset[tuple[str, str]] | None
89 | key_assert_hostname: bool | str | None
90 | key_assert_fingerprint: str | None
91 | key_server_hostname: str | None
92 | key_blocksize: int | None
93 |
94 |
95 | def _default_key_normalizer(
96 | key_class: type[PoolKey], request_context: dict[str, typing.Any]
97 | ) -> PoolKey:
98 | """
99 | Create a pool key out of a request context dictionary.
100 |
101 | According to RFC 3986, both the scheme and host are case-insensitive.
102 | Therefore, this function normalizes both before constructing the pool
103 | key for an HTTPS request. If you wish to change this behaviour, provide
104 | alternate callables to ``key_fn_by_scheme``.
105 |
106 | :param key_class:
107 | The class to use when constructing the key. This should be a namedtuple
108 | with the ``scheme`` and ``host`` keys at a minimum.
109 | :type key_class: namedtuple
110 | :param request_context:
111 | A dictionary-like object that contain the context for a request.
112 | :type request_context: dict
113 |
114 | :return: A namedtuple that can be used as a connection pool key.
115 | :rtype: PoolKey
116 | """
117 | # Since we mutate the dictionary, make a copy first
118 | context = request_context.copy()
119 | context["scheme"] = context["scheme"].lower()
120 | context["host"] = context["host"].lower()
121 |
122 | # These are both dictionaries and need to be transformed into frozensets
123 | for key in ("headers", "_proxy_headers", "_socks_options"):
124 | if key in context and context[key] is not None:
125 | context[key] = frozenset(context[key].items())
126 |
127 | # The socket_options key may be a list and needs to be transformed into a
128 | # tuple.
129 | socket_opts = context.get("socket_options")
130 | if socket_opts is not None:
131 | context["socket_options"] = tuple(socket_opts)
132 |
133 | # Map the kwargs to the names in the namedtuple - this is necessary since
134 | # namedtuples can't have fields starting with '_'.
135 | for key in list(context.keys()):
136 | context["key_" + key] = context.pop(key)
137 |
138 | # Default to ``None`` for keys missing from the context
139 | for field in key_class._fields:
140 | if field not in context:
141 | context[field] = None
142 |
143 | # Default key_blocksize to _DEFAULT_BLOCKSIZE if missing from the context
144 | if context.get("key_blocksize") is None:
145 | context["key_blocksize"] = _DEFAULT_BLOCKSIZE
146 |
147 | return key_class(**context)
148 |
149 |
150 | #: A dictionary that maps a scheme to a callable that creates a pool key.
151 | #: This can be used to alter the way pool keys are constructed, if desired.
152 | #: Each PoolManager makes a copy of this dictionary so they can be configured
153 | #: globally here, or individually on the instance.
154 | key_fn_by_scheme = {
155 | "http": functools.partial(_default_key_normalizer, PoolKey),
156 | "https": functools.partial(_default_key_normalizer, PoolKey),
157 | }
158 |
159 | pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool}
160 |
161 |
162 | class PoolManager(RequestMethods):
163 | """
164 | Allows for arbitrary requests while transparently keeping track of
165 | necessary connection pools for you.
166 |
167 | :param num_pools:
168 | Number of connection pools to cache before discarding the least
169 | recently used pool.
170 |
171 | :param headers:
172 | Headers to include with all requests, unless other headers are given
173 | explicitly.
174 |
175 | :param \\**connection_pool_kw:
176 | Additional parameters are used to create fresh
177 | :class:`urllib3.connectionpool.ConnectionPool` instances.
178 |
179 | Example:
180 |
181 | .. code-block:: python
182 |
183 | import urllib3
184 |
185 | http = urllib3.PoolManager(num_pools=2)
186 |
187 | resp1 = http.request("GET", "https://google.com/")
188 | resp2 = http.request("GET", "https://google.com/mail")
189 | resp3 = http.request("GET", "https://yahoo.com/")
190 |
191 | print(len(http.pools))
192 | # 2
193 |
194 | """
195 |
196 | proxy: Url | None = None
197 | proxy_config: ProxyConfig | None = None
198 |
199 | def __init__(
200 | self,
201 | num_pools: int = 10,
202 | headers: typing.Mapping[str, str] | None = None,
203 | **connection_pool_kw: typing.Any,
204 | ) -> None:
205 | super().__init__(headers)
206 | self.connection_pool_kw = connection_pool_kw
207 |
208 | self.pools: RecentlyUsedContainer[PoolKey, HTTPConnectionPool]
209 | self.pools = RecentlyUsedContainer(num_pools)
210 |
211 | # Locally set the pool classes and keys so other PoolManagers can
212 | # override them.
213 | self.pool_classes_by_scheme = pool_classes_by_scheme
214 | self.key_fn_by_scheme = key_fn_by_scheme.copy()
215 |
216 | def __enter__(self) -> Self:
217 | return self
218 |
219 | def __exit__(
220 | self,
221 | exc_type: type[BaseException] | None,
222 | exc_val: BaseException | None,
223 | exc_tb: TracebackType | None,
224 | ) -> typing.Literal[False]:
225 | self.clear()
226 | # Return False to re-raise any potential exceptions
227 | return False
228 |
229 | def _new_pool(
230 | self,
231 | scheme: str,
232 | host: str,
233 | port: int,
234 | request_context: dict[str, typing.Any] | None = None,
235 | ) -> HTTPConnectionPool:
236 | """
237 | Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and
238 | any additional pool keyword arguments.
239 |
240 | If ``request_context`` is provided, it is provided as keyword arguments
241 | to the pool class used. This method is used to actually create the
242 | connection pools handed out by :meth:`connection_from_url` and
243 | companion methods. It is intended to be overridden for customization.
244 | """
245 | pool_cls: type[HTTPConnectionPool] = self.pool_classes_by_scheme[scheme]
246 | if request_context is None:
247 | request_context = self.connection_pool_kw.copy()
248 |
249 | # Default blocksize to _DEFAULT_BLOCKSIZE if missing or explicitly
250 | # set to 'None' in the request_context.
251 | if request_context.get("blocksize") is None:
252 | request_context["blocksize"] = _DEFAULT_BLOCKSIZE
253 |
254 | # Although the context has everything necessary to create the pool,
255 | # this function has historically only used the scheme, host, and port
256 | # in the positional args. When an API change is acceptable these can
257 | # be removed.
258 | for key in ("scheme", "host", "port"):
259 | request_context.pop(key, None)
260 |
261 | if scheme == "http":
262 | for kw in SSL_KEYWORDS:
263 | request_context.pop(kw, None)
264 |
265 | return pool_cls(host, port, **request_context)
266 |
267 | def clear(self) -> None:
268 | """
269 | Empty our store of pools and direct them all to close.
270 |
271 | This will not affect in-flight connections, but they will not be
272 | re-used after completion.
273 | """
274 | self.pools.clear()
275 |
276 | def connection_from_host(
277 | self,
278 | host: str | None,
279 | port: int | None = None,
280 | scheme: str | None = "http",
281 | pool_kwargs: dict[str, typing.Any] | None = None,
282 | ) -> HTTPConnectionPool:
283 | """
284 | Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
285 |
286 | If ``port`` isn't given, it will be derived from the ``scheme`` using
287 | ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
288 | provided, it is merged with the instance's ``connection_pool_kw``
289 | variable and used to create the new connection pool, if one is
290 | needed.
291 | """
292 |
293 | if not host:
294 | raise LocationValueError("No host specified.")
295 |
296 | request_context = self._merge_pool_kwargs(pool_kwargs)
297 | request_context["scheme"] = scheme or "http"
298 | if not port:
299 | port = port_by_scheme.get(request_context["scheme"].lower(), 80)
300 | request_context["port"] = port
301 | request_context["host"] = host
302 |
303 | return self.connection_from_context(request_context)
304 |
305 | def connection_from_context(
306 | self, request_context: dict[str, typing.Any]
307 | ) -> HTTPConnectionPool:
308 | """
309 | Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context.
310 |
311 | ``request_context`` must at least contain the ``scheme`` key and its
312 | value must be a key in ``key_fn_by_scheme`` instance variable.
313 | """
314 | if "strict" in request_context:
315 | warnings.warn(
316 | "The 'strict' parameter is no longer needed on Python 3+. "
317 | "This will raise an error in urllib3 v2.1.0.",
318 | DeprecationWarning,
319 | )
320 | request_context.pop("strict")
321 |
322 | scheme = request_context["scheme"].lower()
323 | pool_key_constructor = self.key_fn_by_scheme.get(scheme)
324 | if not pool_key_constructor:
325 | raise URLSchemeUnknown(scheme)
326 | pool_key = pool_key_constructor(request_context)
327 |
328 | return self.connection_from_pool_key(pool_key, request_context=request_context)
329 |
330 | def connection_from_pool_key(
331 | self, pool_key: PoolKey, request_context: dict[str, typing.Any]
332 | ) -> HTTPConnectionPool:
333 | """
334 | Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key.
335 |
336 | ``pool_key`` should be a namedtuple that only contains immutable
337 | objects. At a minimum it must have the ``scheme``, ``host``, and
338 | ``port`` fields.
339 | """
340 | with self.pools.lock:
341 | # If the scheme, host, or port doesn't match existing open
342 | # connections, open a new ConnectionPool.
343 | pool = self.pools.get(pool_key)
344 | if pool:
345 | return pool
346 |
347 | # Make a fresh ConnectionPool of the desired type
348 | scheme = request_context["scheme"]
349 | host = request_context["host"]
350 | port = request_context["port"]
351 | pool = self._new_pool(scheme, host, port, request_context=request_context)
352 | self.pools[pool_key] = pool
353 |
354 | return pool
355 |
356 | def connection_from_url(
357 | self, url: str, pool_kwargs: dict[str, typing.Any] | None = None
358 | ) -> HTTPConnectionPool:
359 | """
360 | Similar to :func:`urllib3.connectionpool.connection_from_url`.
361 |
362 | If ``pool_kwargs`` is not provided and a new pool needs to be
363 | constructed, ``self.connection_pool_kw`` is used to initialize
364 | the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs``
365 | is provided, it is used instead. Note that if a new pool does not
366 | need to be created for the request, the provided ``pool_kwargs`` are
367 | not used.
368 | """
369 | u = parse_url(url)
370 | return self.connection_from_host(
371 | u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs
372 | )
373 |
374 | def _merge_pool_kwargs(
375 | self, override: dict[str, typing.Any] | None
376 | ) -> dict[str, typing.Any]:
377 | """
378 | Merge a dictionary of override values for self.connection_pool_kw.
379 |
380 | This does not modify self.connection_pool_kw and returns a new dict.
381 | Any keys in the override dictionary with a value of ``None`` are
382 | removed from the merged dictionary.
383 | """
384 | base_pool_kwargs = self.connection_pool_kw.copy()
385 | if override:
386 | for key, value in override.items():
387 | if value is None:
388 | try:
389 | del base_pool_kwargs[key]
390 | except KeyError:
391 | pass
392 | else:
393 | base_pool_kwargs[key] = value
394 | return base_pool_kwargs
395 |
396 | def _proxy_requires_url_absolute_form(self, parsed_url: Url) -> bool:
397 | """
398 | Indicates if the proxy requires the complete destination URL in the
399 | request. Normally this is only needed when not using an HTTP CONNECT
400 | tunnel.
401 | """
402 | if self.proxy is None:
403 | return False
404 |
405 | return not connection_requires_http_tunnel(
406 | self.proxy, self.proxy_config, parsed_url.scheme
407 | )
408 |
409 | def urlopen( # type: ignore[override]
410 | self, method: str, url: str, redirect: bool = True, **kw: typing.Any
411 | ) -> BaseHTTPResponse:
412 | """
413 | Same as :meth:`urllib3.HTTPConnectionPool.urlopen`
414 | with custom cross-host redirect logic and only sends the request-uri
415 | portion of the ``url``.
416 |
417 | The given ``url`` parameter must be absolute, such that an appropriate
418 | :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
419 | """
420 | u = parse_url(url)
421 |
422 | if u.scheme is None:
423 | warnings.warn(
424 | "URLs without a scheme (ie 'https://') are deprecated and will raise an error "
425 | "in a future version of urllib3. To avoid this DeprecationWarning ensure all URLs "
426 | "start with 'https://' or 'http://'. Read more in this issue: "
427 | "https://github.com/urllib3/urllib3/issues/2920",
428 | category=DeprecationWarning,
429 | stacklevel=2,
430 | )
431 |
432 | conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
433 |
434 | kw["assert_same_host"] = False
435 | kw["redirect"] = False
436 |
437 | if "headers" not in kw:
438 | kw["headers"] = self.headers
439 |
440 | if self._proxy_requires_url_absolute_form(u):
441 | response = conn.urlopen(method, url, **kw)
442 | else:
443 | response = conn.urlopen(method, u.request_uri, **kw)
444 |
445 | redirect_location = redirect and response.get_redirect_location()
446 | if not redirect_location:
447 | return response
448 |
449 | # Support relative URLs for redirecting.
450 | redirect_location = urljoin(url, redirect_location)
451 |
452 | if response.status == 303:
453 | # Change the method according to RFC 9110, Section 15.4.4.
454 | method = "GET"
455 | # And lose the body not to transfer anything sensitive.
456 | kw["body"] = None
457 | kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change()
458 |
459 | retries = kw.get("retries")
460 | if not isinstance(retries, Retry):
461 | retries = Retry.from_int(retries, redirect=redirect)
462 |
463 | # Strip headers marked as unsafe to forward to the redirected location.
464 | # Check remove_headers_on_redirect to avoid a potential network call within
465 | # conn.is_same_host() which may use socket.gethostbyname() in the future.
466 | if retries.remove_headers_on_redirect and not conn.is_same_host(
467 | redirect_location
468 | ):
469 | new_headers = kw["headers"].copy()
470 | for header in kw["headers"]:
471 | if header.lower() in retries.remove_headers_on_redirect:
472 | new_headers.pop(header, None)
473 | kw["headers"] = new_headers
474 |
475 | try:
476 | retries = retries.increment(method, url, response=response, _pool=conn)
477 | except MaxRetryError:
478 | if retries.raise_on_redirect:
479 | response.drain_conn()
480 | raise
481 | return response
482 |
483 | kw["retries"] = retries
484 | kw["redirect"] = redirect
485 |
486 | log.info("Redirecting %s -> %s", url, redirect_location)
487 |
488 | response.drain_conn()
489 | return self.urlopen(method, redirect_location, **kw)
490 |
491 |
492 | class ProxyManager(PoolManager):
493 | """
494 | Behaves just like :class:`PoolManager`, but sends all requests through
495 | the defined proxy, using the CONNECT method for HTTPS URLs.
496 |
497 | :param proxy_url:
498 | The URL of the proxy to be used.
499 |
500 | :param proxy_headers:
501 | A dictionary containing headers that will be sent to the proxy. In case
502 | of HTTP they are being sent with each request, while in the
503 | HTTPS/CONNECT case they are sent only once. Could be used for proxy
504 | authentication.
505 |
506 | :param proxy_ssl_context:
507 | The proxy SSL context is used to establish the TLS connection to the
508 | proxy when using HTTPS proxies.
509 |
510 | :param use_forwarding_for_https:
511 | (Defaults to False) If set to True will forward requests to the HTTPS
512 | proxy to be made on behalf of the client instead of creating a TLS
513 | tunnel via the CONNECT method. **Enabling this flag means that request
514 | and response headers and content will be visible from the HTTPS proxy**
515 | whereas tunneling keeps request and response headers and content
516 | private. IP address, target hostname, SNI, and port are always visible
517 | to an HTTPS proxy even when this flag is disabled.
518 |
519 | :param proxy_assert_hostname:
520 | The hostname of the certificate to verify against.
521 |
522 | :param proxy_assert_fingerprint:
523 | The fingerprint of the certificate to verify against.
524 |
525 | Example:
526 |
527 | .. code-block:: python
528 |
529 | import urllib3
530 |
531 | proxy = urllib3.ProxyManager("https://localhost:3128/")
532 |
533 | resp1 = proxy.request("GET", "https://google.com/")
534 | resp2 = proxy.request("GET", "https://httpbin.org/")
535 |
536 | print(len(proxy.pools))
537 | # 1
538 |
539 | resp3 = proxy.request("GET", "https://httpbin.org/")
540 | resp4 = proxy.request("GET", "https://twitter.com/")
541 |
542 | print(len(proxy.pools))
543 | # 3
544 |
545 | """
546 |
547 | def __init__(
548 | self,
549 | proxy_url: str,
550 | num_pools: int = 10,
551 | headers: typing.Mapping[str, str] | None = None,
552 | proxy_headers: typing.Mapping[str, str] | None = None,
553 | proxy_ssl_context: ssl.SSLContext | None = None,
554 | use_forwarding_for_https: bool = False,
555 | proxy_assert_hostname: None | str | typing.Literal[False] = None,
556 | proxy_assert_fingerprint: str | None = None,
557 | **connection_pool_kw: typing.Any,
558 | ) -> None:
559 | if isinstance(proxy_url, HTTPConnectionPool):
560 | str_proxy_url = f"{proxy_url.scheme}://{proxy_url.host}:{proxy_url.port}"
561 | else:
562 | str_proxy_url = proxy_url
563 | proxy = parse_url(str_proxy_url)
564 |
565 | if proxy.scheme not in ("http", "https"):
566 | raise ProxySchemeUnknown(proxy.scheme)
567 |
568 | if not proxy.port:
569 | port = port_by_scheme.get(proxy.scheme, 80)
570 | proxy = proxy._replace(port=port)
571 |
572 | self.proxy = proxy
573 | self.proxy_headers = proxy_headers or {}
574 | self.proxy_ssl_context = proxy_ssl_context
575 | self.proxy_config = ProxyConfig(
576 | proxy_ssl_context,
577 | use_forwarding_for_https,
578 | proxy_assert_hostname,
579 | proxy_assert_fingerprint,
580 | )
581 |
582 | connection_pool_kw["_proxy"] = self.proxy
583 | connection_pool_kw["_proxy_headers"] = self.proxy_headers
584 | connection_pool_kw["_proxy_config"] = self.proxy_config
585 |
586 | super().__init__(num_pools, headers, **connection_pool_kw)
587 |
588 | def connection_from_host(
589 | self,
590 | host: str | None,
591 | port: int | None = None,
592 | scheme: str | None = "http",
593 | pool_kwargs: dict[str, typing.Any] | None = None,
594 | ) -> HTTPConnectionPool:
595 | if scheme == "https":
596 | return super().connection_from_host(
597 | host, port, scheme, pool_kwargs=pool_kwargs
598 | )
599 |
600 | return super().connection_from_host(
601 | self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs # type: ignore[union-attr]
602 | )
603 |
604 | def _set_proxy_headers(
605 | self, url: str, headers: typing.Mapping[str, str] | None = None
606 | ) -> typing.Mapping[str, str]:
607 | """
608 | Sets headers needed by proxies: specifically, the Accept and Host
609 | headers. Only sets headers not provided by the user.
610 | """
611 | headers_ = {"Accept": "*/*"}
612 |
613 | netloc = parse_url(url).netloc
614 | if netloc:
615 | headers_["Host"] = netloc
616 |
617 | if headers:
618 | headers_.update(headers)
619 | return headers_
620 |
621 | def urlopen( # type: ignore[override]
622 | self, method: str, url: str, redirect: bool = True, **kw: typing.Any
623 | ) -> BaseHTTPResponse:
624 | "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
625 | u = parse_url(url)
626 | if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme):
627 | # For connections using HTTP CONNECT, httplib sets the necessary
628 | # headers on the CONNECT to the proxy. If we're not using CONNECT,
629 | # we'll definitely need to set 'Host' at the very least.
630 | headers = kw.get("headers", self.headers)
631 | kw["headers"] = self._set_proxy_headers(url, headers)
632 |
633 | return super().urlopen(method, url, redirect=redirect, **kw)
634 |
635 |
636 | def proxy_from_url(url: str, **kw: typing.Any) -> ProxyManager:
637 | return ProxyManager(proxy_url=url, **kw)
638 |
```