#
tokens: 48908/50000 3/808 files (page 67/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 67 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/urllib3/contrib/pyopenssl.py:
--------------------------------------------------------------------------------

```python
  1 | """
  2 | Module for using pyOpenSSL as a TLS backend. This module was relevant before
  3 | the standard library ``ssl`` module supported SNI, but now that we've dropped
  4 | support for Python 2.7 all relevant Python versions support SNI so
  5 | **this module is no longer recommended**.
  6 | 
  7 | This needs the following packages installed:
  8 | 
  9 | * `pyOpenSSL`_ (tested with 16.0.0)
 10 | * `cryptography`_ (minimum 1.3.4, from pyopenssl)
 11 | * `idna`_ (minimum 2.0)
 12 | 
 13 | However, pyOpenSSL depends on cryptography, so while we use all three directly here we
 14 | end up having relatively few packages required.
 15 | 
 16 | You can install them with the following command:
 17 | 
 18 | .. code-block:: bash
 19 | 
 20 |     $ python -m pip install pyopenssl cryptography idna
 21 | 
 22 | To activate certificate checking, call
 23 | :func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code
 24 | before you begin making HTTP requests. This can be done in a ``sitecustomize``
 25 | module, or at any other time before your application begins using ``urllib3``,
 26 | like this:
 27 | 
 28 | .. code-block:: python
 29 | 
 30 |     try:
 31 |         import urllib3.contrib.pyopenssl
 32 |         urllib3.contrib.pyopenssl.inject_into_urllib3()
 33 |     except ImportError:
 34 |         pass
 35 | 
 36 | .. _pyopenssl: https://www.pyopenssl.org
 37 | .. _cryptography: https://cryptography.io
 38 | .. _idna: https://github.com/kjd/idna
 39 | """
 40 | 
 41 | from __future__ import annotations
 42 | 
 43 | import OpenSSL.SSL  # type: ignore[import-untyped]
 44 | from cryptography import x509
 45 | 
 46 | try:
 47 |     from cryptography.x509 import UnsupportedExtension  # type: ignore[attr-defined]
 48 | except ImportError:
 49 |     # UnsupportedExtension is gone in cryptography >= 2.1.0
 50 |     class UnsupportedExtension(Exception):  # type: ignore[no-redef]
 51 |         pass
 52 | 
 53 | 
 54 | import logging
 55 | import ssl
 56 | import typing
 57 | from io import BytesIO
 58 | from socket import socket as socket_cls
 59 | from socket import timeout
 60 | 
 61 | from .. import util
 62 | 
 63 | if typing.TYPE_CHECKING:
 64 |     from OpenSSL.crypto import X509  # type: ignore[import-untyped]
 65 | 
 66 | 
 67 | __all__ = ["inject_into_urllib3", "extract_from_urllib3"]
 68 | 
 69 | # Map from urllib3 to PyOpenSSL compatible parameter-values.
 70 | _openssl_versions: dict[int, int] = {
 71 |     util.ssl_.PROTOCOL_TLS: OpenSSL.SSL.SSLv23_METHOD,  # type: ignore[attr-defined]
 72 |     util.ssl_.PROTOCOL_TLS_CLIENT: OpenSSL.SSL.SSLv23_METHOD,  # type: ignore[attr-defined]
 73 |     ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
 74 | }
 75 | 
 76 | if hasattr(ssl, "PROTOCOL_TLSv1_1") and hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"):
 77 |     _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD
 78 | 
 79 | if hasattr(ssl, "PROTOCOL_TLSv1_2") and hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"):
 80 |     _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD
 81 | 
 82 | 
 83 | _stdlib_to_openssl_verify = {
 84 |     ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,
 85 |     ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,
 86 |     ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER
 87 |     + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
 88 | }
 89 | _openssl_to_stdlib_verify = {v: k for k, v in _stdlib_to_openssl_verify.items()}
 90 | 
 91 | # The SSLvX values are the most likely to be missing in the future
 92 | # but we check them all just to be sure.
 93 | _OP_NO_SSLv2_OR_SSLv3: int = getattr(OpenSSL.SSL, "OP_NO_SSLv2", 0) | getattr(
 94 |     OpenSSL.SSL, "OP_NO_SSLv3", 0
 95 | )
 96 | _OP_NO_TLSv1: int = getattr(OpenSSL.SSL, "OP_NO_TLSv1", 0)
 97 | _OP_NO_TLSv1_1: int = getattr(OpenSSL.SSL, "OP_NO_TLSv1_1", 0)
 98 | _OP_NO_TLSv1_2: int = getattr(OpenSSL.SSL, "OP_NO_TLSv1_2", 0)
 99 | _OP_NO_TLSv1_3: int = getattr(OpenSSL.SSL, "OP_NO_TLSv1_3", 0)
100 | 
101 | _openssl_to_ssl_minimum_version: dict[int, int] = {
102 |     ssl.TLSVersion.MINIMUM_SUPPORTED: _OP_NO_SSLv2_OR_SSLv3,
103 |     ssl.TLSVersion.TLSv1: _OP_NO_SSLv2_OR_SSLv3,
104 |     ssl.TLSVersion.TLSv1_1: _OP_NO_SSLv2_OR_SSLv3 | _OP_NO_TLSv1,
105 |     ssl.TLSVersion.TLSv1_2: _OP_NO_SSLv2_OR_SSLv3 | _OP_NO_TLSv1 | _OP_NO_TLSv1_1,
106 |     ssl.TLSVersion.TLSv1_3: (
107 |         _OP_NO_SSLv2_OR_SSLv3 | _OP_NO_TLSv1 | _OP_NO_TLSv1_1 | _OP_NO_TLSv1_2
108 |     ),
109 |     ssl.TLSVersion.MAXIMUM_SUPPORTED: (
110 |         _OP_NO_SSLv2_OR_SSLv3 | _OP_NO_TLSv1 | _OP_NO_TLSv1_1 | _OP_NO_TLSv1_2
111 |     ),
112 | }
113 | _openssl_to_ssl_maximum_version: dict[int, int] = {
114 |     ssl.TLSVersion.MINIMUM_SUPPORTED: (
115 |         _OP_NO_SSLv2_OR_SSLv3
116 |         | _OP_NO_TLSv1
117 |         | _OP_NO_TLSv1_1
118 |         | _OP_NO_TLSv1_2
119 |         | _OP_NO_TLSv1_3
120 |     ),
121 |     ssl.TLSVersion.TLSv1: (
122 |         _OP_NO_SSLv2_OR_SSLv3 | _OP_NO_TLSv1_1 | _OP_NO_TLSv1_2 | _OP_NO_TLSv1_3
123 |     ),
124 |     ssl.TLSVersion.TLSv1_1: _OP_NO_SSLv2_OR_SSLv3 | _OP_NO_TLSv1_2 | _OP_NO_TLSv1_3,
125 |     ssl.TLSVersion.TLSv1_2: _OP_NO_SSLv2_OR_SSLv3 | _OP_NO_TLSv1_3,
126 |     ssl.TLSVersion.TLSv1_3: _OP_NO_SSLv2_OR_SSLv3,
127 |     ssl.TLSVersion.MAXIMUM_SUPPORTED: _OP_NO_SSLv2_OR_SSLv3,
128 | }
129 | 
130 | # OpenSSL will only write 16K at a time
131 | SSL_WRITE_BLOCKSIZE = 16384
132 | 
133 | orig_util_SSLContext = util.ssl_.SSLContext
134 | 
135 | 
136 | log = logging.getLogger(__name__)
137 | 
138 | 
139 | def inject_into_urllib3() -> None:
140 |     "Monkey-patch urllib3 with PyOpenSSL-backed SSL-support."
141 | 
142 |     _validate_dependencies_met()
143 | 
144 |     util.SSLContext = PyOpenSSLContext  # type: ignore[assignment]
145 |     util.ssl_.SSLContext = PyOpenSSLContext  # type: ignore[assignment]
146 |     util.IS_PYOPENSSL = True
147 |     util.ssl_.IS_PYOPENSSL = True
148 | 
149 | 
150 | def extract_from_urllib3() -> None:
151 |     "Undo monkey-patching by :func:`inject_into_urllib3`."
152 | 
153 |     util.SSLContext = orig_util_SSLContext
154 |     util.ssl_.SSLContext = orig_util_SSLContext
155 |     util.IS_PYOPENSSL = False
156 |     util.ssl_.IS_PYOPENSSL = False
157 | 
158 | 
159 | def _validate_dependencies_met() -> None:
160 |     """
161 |     Verifies that PyOpenSSL's package-level dependencies have been met.
162 |     Throws `ImportError` if they are not met.
163 |     """
164 |     # Method added in `cryptography==1.1`; not available in older versions
165 |     from cryptography.x509.extensions import Extensions
166 | 
167 |     if getattr(Extensions, "get_extension_for_class", None) is None:
168 |         raise ImportError(
169 |             "'cryptography' module missing required functionality.  "
170 |             "Try upgrading to v1.3.4 or newer."
171 |         )
172 | 
173 |     # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509
174 |     # attribute is only present on those versions.
175 |     from OpenSSL.crypto import X509
176 | 
177 |     x509 = X509()
178 |     if getattr(x509, "_x509", None) is None:
179 |         raise ImportError(
180 |             "'pyOpenSSL' module missing required functionality. "
181 |             "Try upgrading to v0.14 or newer."
182 |         )
183 | 
184 | 
185 | def _dnsname_to_stdlib(name: str) -> str | None:
186 |     """
187 |     Converts a dNSName SubjectAlternativeName field to the form used by the
188 |     standard library on the given Python version.
189 | 
190 |     Cryptography produces a dNSName as a unicode string that was idna-decoded
191 |     from ASCII bytes. We need to idna-encode that string to get it back, and
192 |     then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib
193 |     uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8).
194 | 
195 |     If the name cannot be idna-encoded then we return None signalling that
196 |     the name given should be skipped.
197 |     """
198 | 
199 |     def idna_encode(name: str) -> bytes | None:
200 |         """
201 |         Borrowed wholesale from the Python Cryptography Project. It turns out
202 |         that we can't just safely call `idna.encode`: it can explode for
203 |         wildcard names. This avoids that problem.
204 |         """
205 |         import idna
206 | 
207 |         try:
208 |             for prefix in ["*.", "."]:
209 |                 if name.startswith(prefix):
210 |                     name = name[len(prefix) :]
211 |                     return prefix.encode("ascii") + idna.encode(name)
212 |             return idna.encode(name)
213 |         except idna.core.IDNAError:
214 |             return None
215 | 
216 |     # Don't send IPv6 addresses through the IDNA encoder.
217 |     if ":" in name:
218 |         return name
219 | 
220 |     encoded_name = idna_encode(name)
221 |     if encoded_name is None:
222 |         return None
223 |     return encoded_name.decode("utf-8")
224 | 
225 | 
226 | def get_subj_alt_name(peer_cert: X509) -> list[tuple[str, str]]:
227 |     """
228 |     Given an PyOpenSSL certificate, provides all the subject alternative names.
229 |     """
230 |     cert = peer_cert.to_cryptography()
231 | 
232 |     # We want to find the SAN extension. Ask Cryptography to locate it (it's
233 |     # faster than looping in Python)
234 |     try:
235 |         ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value
236 |     except x509.ExtensionNotFound:
237 |         # No such extension, return the empty list.
238 |         return []
239 |     except (
240 |         x509.DuplicateExtension,
241 |         UnsupportedExtension,
242 |         x509.UnsupportedGeneralNameType,
243 |         UnicodeError,
244 |     ) as e:
245 |         # A problem has been found with the quality of the certificate. Assume
246 |         # no SAN field is present.
247 |         log.warning(
248 |             "A problem was encountered with the certificate that prevented "
249 |             "urllib3 from finding the SubjectAlternativeName field. This can "
250 |             "affect certificate validation. The error was %s",
251 |             e,
252 |         )
253 |         return []
254 | 
255 |     # We want to return dNSName and iPAddress fields. We need to cast the IPs
256 |     # back to strings because the match_hostname function wants them as
257 |     # strings.
258 |     # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8
259 |     # decoded. This is pretty frustrating, but that's what the standard library
260 |     # does with certificates, and so we need to attempt to do the same.
261 |     # We also want to skip over names which cannot be idna encoded.
262 |     names = [
263 |         ("DNS", name)
264 |         for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName))
265 |         if name is not None
266 |     ]
267 |     names.extend(
268 |         ("IP Address", str(name)) for name in ext.get_values_for_type(x509.IPAddress)
269 |     )
270 | 
271 |     return names
272 | 
273 | 
274 | class WrappedSocket:
275 |     """API-compatibility wrapper for Python OpenSSL's Connection-class."""
276 | 
277 |     def __init__(
278 |         self,
279 |         connection: OpenSSL.SSL.Connection,
280 |         socket: socket_cls,
281 |         suppress_ragged_eofs: bool = True,
282 |     ) -> None:
283 |         self.connection = connection
284 |         self.socket = socket
285 |         self.suppress_ragged_eofs = suppress_ragged_eofs
286 |         self._io_refs = 0
287 |         self._closed = False
288 | 
289 |     def fileno(self) -> int:
290 |         return self.socket.fileno()
291 | 
292 |     # Copy-pasted from Python 3.5 source code
293 |     def _decref_socketios(self) -> None:
294 |         if self._io_refs > 0:
295 |             self._io_refs -= 1
296 |         if self._closed:
297 |             self.close()
298 | 
299 |     def recv(self, *args: typing.Any, **kwargs: typing.Any) -> bytes:
300 |         try:
301 |             data = self.connection.recv(*args, **kwargs)
302 |         except OpenSSL.SSL.SysCallError as e:
303 |             if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"):
304 |                 return b""
305 |             else:
306 |                 raise OSError(e.args[0], str(e)) from e
307 |         except OpenSSL.SSL.ZeroReturnError:
308 |             if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
309 |                 return b""
310 |             else:
311 |                 raise
312 |         except OpenSSL.SSL.WantReadError as e:
313 |             if not util.wait_for_read(self.socket, self.socket.gettimeout()):
314 |                 raise timeout("The read operation timed out") from e
315 |             else:
316 |                 return self.recv(*args, **kwargs)
317 | 
318 |         # TLS 1.3 post-handshake authentication
319 |         except OpenSSL.SSL.Error as e:
320 |             raise ssl.SSLError(f"read error: {e!r}") from e
321 |         else:
322 |             return data  # type: ignore[no-any-return]
323 | 
324 |     def recv_into(self, *args: typing.Any, **kwargs: typing.Any) -> int:
325 |         try:
326 |             return self.connection.recv_into(*args, **kwargs)  # type: ignore[no-any-return]
327 |         except OpenSSL.SSL.SysCallError as e:
328 |             if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"):
329 |                 return 0
330 |             else:
331 |                 raise OSError(e.args[0], str(e)) from e
332 |         except OpenSSL.SSL.ZeroReturnError:
333 |             if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
334 |                 return 0
335 |             else:
336 |                 raise
337 |         except OpenSSL.SSL.WantReadError as e:
338 |             if not util.wait_for_read(self.socket, self.socket.gettimeout()):
339 |                 raise timeout("The read operation timed out") from e
340 |             else:
341 |                 return self.recv_into(*args, **kwargs)
342 | 
343 |         # TLS 1.3 post-handshake authentication
344 |         except OpenSSL.SSL.Error as e:
345 |             raise ssl.SSLError(f"read error: {e!r}") from e
346 | 
347 |     def settimeout(self, timeout: float) -> None:
348 |         return self.socket.settimeout(timeout)
349 | 
350 |     def _send_until_done(self, data: bytes) -> int:
351 |         while True:
352 |             try:
353 |                 return self.connection.send(data)  # type: ignore[no-any-return]
354 |             except OpenSSL.SSL.WantWriteError as e:
355 |                 if not util.wait_for_write(self.socket, self.socket.gettimeout()):
356 |                     raise timeout() from e
357 |                 continue
358 |             except OpenSSL.SSL.SysCallError as e:
359 |                 raise OSError(e.args[0], str(e)) from e
360 | 
361 |     def sendall(self, data: bytes) -> None:
362 |         total_sent = 0
363 |         while total_sent < len(data):
364 |             sent = self._send_until_done(
365 |                 data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE]
366 |             )
367 |             total_sent += sent
368 | 
369 |     def shutdown(self) -> None:
370 |         # FIXME rethrow compatible exceptions should we ever use this
371 |         self.connection.shutdown()
372 | 
373 |     def close(self) -> None:
374 |         self._closed = True
375 |         if self._io_refs <= 0:
376 |             self._real_close()
377 | 
378 |     def _real_close(self) -> None:
379 |         try:
380 |             return self.connection.close()  # type: ignore[no-any-return]
381 |         except OpenSSL.SSL.Error:
382 |             return
383 | 
384 |     def getpeercert(
385 |         self, binary_form: bool = False
386 |     ) -> dict[str, list[typing.Any]] | None:
387 |         x509 = self.connection.get_peer_certificate()
388 | 
389 |         if not x509:
390 |             return x509  # type: ignore[no-any-return]
391 | 
392 |         if binary_form:
393 |             return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, x509)  # type: ignore[no-any-return]
394 | 
395 |         return {
396 |             "subject": ((("commonName", x509.get_subject().CN),),),  # type: ignore[dict-item]
397 |             "subjectAltName": get_subj_alt_name(x509),
398 |         }
399 | 
400 |     def version(self) -> str:
401 |         return self.connection.get_protocol_version_name()  # type: ignore[no-any-return]
402 | 
403 |     def selected_alpn_protocol(self) -> str | None:
404 |         alpn_proto = self.connection.get_alpn_proto_negotiated()
405 |         return alpn_proto.decode() if alpn_proto else None
406 | 
407 | 
408 | WrappedSocket.makefile = socket_cls.makefile  # type: ignore[attr-defined]
409 | 
410 | 
411 | class PyOpenSSLContext:
412 |     """
413 |     I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible
414 |     for translating the interface of the standard library ``SSLContext`` object
415 |     to calls into PyOpenSSL.
416 |     """
417 | 
418 |     def __init__(self, protocol: int) -> None:
419 |         self.protocol = _openssl_versions[protocol]
420 |         self._ctx = OpenSSL.SSL.Context(self.protocol)
421 |         self._options = 0
422 |         self.check_hostname = False
423 |         self._minimum_version: int = ssl.TLSVersion.MINIMUM_SUPPORTED
424 |         self._maximum_version: int = ssl.TLSVersion.MAXIMUM_SUPPORTED
425 | 
426 |     @property
427 |     def options(self) -> int:
428 |         return self._options
429 | 
430 |     @options.setter
431 |     def options(self, value: int) -> None:
432 |         self._options = value
433 |         self._set_ctx_options()
434 | 
435 |     @property
436 |     def verify_mode(self) -> int:
437 |         return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()]
438 | 
439 |     @verify_mode.setter
440 |     def verify_mode(self, value: ssl.VerifyMode) -> None:
441 |         self._ctx.set_verify(_stdlib_to_openssl_verify[value], _verify_callback)
442 | 
443 |     def set_default_verify_paths(self) -> None:
444 |         self._ctx.set_default_verify_paths()
445 | 
446 |     def set_ciphers(self, ciphers: bytes | str) -> None:
447 |         if isinstance(ciphers, str):
448 |             ciphers = ciphers.encode("utf-8")
449 |         self._ctx.set_cipher_list(ciphers)
450 | 
451 |     def load_verify_locations(
452 |         self,
453 |         cafile: str | None = None,
454 |         capath: str | None = None,
455 |         cadata: bytes | None = None,
456 |     ) -> None:
457 |         if cafile is not None:
458 |             cafile = cafile.encode("utf-8")  # type: ignore[assignment]
459 |         if capath is not None:
460 |             capath = capath.encode("utf-8")  # type: ignore[assignment]
461 |         try:
462 |             self._ctx.load_verify_locations(cafile, capath)
463 |             if cadata is not None:
464 |                 self._ctx.load_verify_locations(BytesIO(cadata))
465 |         except OpenSSL.SSL.Error as e:
466 |             raise ssl.SSLError(f"unable to load trusted certificates: {e!r}") from e
467 | 
468 |     def load_cert_chain(
469 |         self,
470 |         certfile: str,
471 |         keyfile: str | None = None,
472 |         password: str | None = None,
473 |     ) -> None:
474 |         try:
475 |             self._ctx.use_certificate_chain_file(certfile)
476 |             if password is not None:
477 |                 if not isinstance(password, bytes):
478 |                     password = password.encode("utf-8")  # type: ignore[assignment]
479 |                 self._ctx.set_passwd_cb(lambda *_: password)
480 |             self._ctx.use_privatekey_file(keyfile or certfile)
481 |         except OpenSSL.SSL.Error as e:
482 |             raise ssl.SSLError(f"Unable to load certificate chain: {e!r}") from e
483 | 
484 |     def set_alpn_protocols(self, protocols: list[bytes | str]) -> None:
485 |         protocols = [util.util.to_bytes(p, "ascii") for p in protocols]
486 |         return self._ctx.set_alpn_protos(protocols)  # type: ignore[no-any-return]
487 | 
488 |     def wrap_socket(
489 |         self,
490 |         sock: socket_cls,
491 |         server_side: bool = False,
492 |         do_handshake_on_connect: bool = True,
493 |         suppress_ragged_eofs: bool = True,
494 |         server_hostname: bytes | str | None = None,
495 |     ) -> WrappedSocket:
496 |         cnx = OpenSSL.SSL.Connection(self._ctx, sock)
497 | 
498 |         # If server_hostname is an IP, don't use it for SNI, per RFC6066 Section 3
499 |         if server_hostname and not util.ssl_.is_ipaddress(server_hostname):
500 |             if isinstance(server_hostname, str):
501 |                 server_hostname = server_hostname.encode("utf-8")
502 |             cnx.set_tlsext_host_name(server_hostname)
503 | 
504 |         cnx.set_connect_state()
505 | 
506 |         while True:
507 |             try:
508 |                 cnx.do_handshake()
509 |             except OpenSSL.SSL.WantReadError as e:
510 |                 if not util.wait_for_read(sock, sock.gettimeout()):
511 |                     raise timeout("select timed out") from e
512 |                 continue
513 |             except OpenSSL.SSL.Error as e:
514 |                 raise ssl.SSLError(f"bad handshake: {e!r}") from e
515 |             break
516 | 
517 |         return WrappedSocket(cnx, sock)
518 | 
519 |     def _set_ctx_options(self) -> None:
520 |         self._ctx.set_options(
521 |             self._options
522 |             | _openssl_to_ssl_minimum_version[self._minimum_version]
523 |             | _openssl_to_ssl_maximum_version[self._maximum_version]
524 |         )
525 | 
526 |     @property
527 |     def minimum_version(self) -> int:
528 |         return self._minimum_version
529 | 
530 |     @minimum_version.setter
531 |     def minimum_version(self, minimum_version: int) -> None:
532 |         self._minimum_version = minimum_version
533 |         self._set_ctx_options()
534 | 
535 |     @property
536 |     def maximum_version(self) -> int:
537 |         return self._maximum_version
538 | 
539 |     @maximum_version.setter
540 |     def maximum_version(self, maximum_version: int) -> None:
541 |         self._maximum_version = maximum_version
542 |         self._set_ctx_options()
543 | 
544 | 
545 | def _verify_callback(
546 |     cnx: OpenSSL.SSL.Connection,
547 |     x509: X509,
548 |     err_no: int,
549 |     err_depth: int,
550 |     return_code: int,
551 | ) -> bool:
552 |     return err_no == 0
553 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/candidates.py:
--------------------------------------------------------------------------------

```python
  1 | import logging
  2 | import sys
  3 | from typing import TYPE_CHECKING, Any, FrozenSet, Iterable, Optional, Tuple, Union, cast
  4 | 
  5 | from pip._vendor.packaging.requirements import InvalidRequirement
  6 | from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
  7 | from pip._vendor.packaging.version import Version
  8 | 
  9 | from pip._internal.exceptions import (
 10 |     HashError,
 11 |     InstallationSubprocessError,
 12 |     MetadataInconsistent,
 13 |     MetadataInvalid,
 14 | )
 15 | from pip._internal.metadata import BaseDistribution
 16 | from pip._internal.models.link import Link, links_equivalent
 17 | from pip._internal.models.wheel import Wheel
 18 | from pip._internal.req.constructors import (
 19 |     install_req_from_editable,
 20 |     install_req_from_line,
 21 | )
 22 | from pip._internal.req.req_install import InstallRequirement
 23 | from pip._internal.utils.direct_url_helpers import direct_url_from_link
 24 | from pip._internal.utils.misc import normalize_version_info
 25 | 
 26 | from .base import Candidate, Requirement, format_name
 27 | 
 28 | if TYPE_CHECKING:
 29 |     from .factory import Factory
 30 | 
 31 | logger = logging.getLogger(__name__)
 32 | 
 33 | BaseCandidate = Union[
 34 |     "AlreadyInstalledCandidate",
 35 |     "EditableCandidate",
 36 |     "LinkCandidate",
 37 | ]
 38 | 
 39 | # Avoid conflicting with the PyPI package "Python".
 40 | REQUIRES_PYTHON_IDENTIFIER = cast(NormalizedName, "<Python from Requires-Python>")
 41 | 
 42 | 
 43 | def as_base_candidate(candidate: Candidate) -> Optional[BaseCandidate]:
 44 |     """The runtime version of BaseCandidate."""
 45 |     base_candidate_classes = (
 46 |         AlreadyInstalledCandidate,
 47 |         EditableCandidate,
 48 |         LinkCandidate,
 49 |     )
 50 |     if isinstance(candidate, base_candidate_classes):
 51 |         return candidate
 52 |     return None
 53 | 
 54 | 
 55 | def make_install_req_from_link(
 56 |     link: Link, template: InstallRequirement
 57 | ) -> InstallRequirement:
 58 |     assert not template.editable, "template is editable"
 59 |     if template.req:
 60 |         line = str(template.req)
 61 |     else:
 62 |         line = link.url
 63 |     ireq = install_req_from_line(
 64 |         line,
 65 |         user_supplied=template.user_supplied,
 66 |         comes_from=template.comes_from,
 67 |         use_pep517=template.use_pep517,
 68 |         isolated=template.isolated,
 69 |         constraint=template.constraint,
 70 |         global_options=template.global_options,
 71 |         hash_options=template.hash_options,
 72 |         config_settings=template.config_settings,
 73 |     )
 74 |     ireq.original_link = template.original_link
 75 |     ireq.link = link
 76 |     ireq.extras = template.extras
 77 |     return ireq
 78 | 
 79 | 
 80 | def make_install_req_from_editable(
 81 |     link: Link, template: InstallRequirement
 82 | ) -> InstallRequirement:
 83 |     assert template.editable, "template not editable"
 84 |     ireq = install_req_from_editable(
 85 |         link.url,
 86 |         user_supplied=template.user_supplied,
 87 |         comes_from=template.comes_from,
 88 |         use_pep517=template.use_pep517,
 89 |         isolated=template.isolated,
 90 |         constraint=template.constraint,
 91 |         permit_editable_wheels=template.permit_editable_wheels,
 92 |         global_options=template.global_options,
 93 |         hash_options=template.hash_options,
 94 |         config_settings=template.config_settings,
 95 |     )
 96 |     ireq.extras = template.extras
 97 |     return ireq
 98 | 
 99 | 
100 | def _make_install_req_from_dist(
101 |     dist: BaseDistribution, template: InstallRequirement
102 | ) -> InstallRequirement:
103 |     if template.req:
104 |         line = str(template.req)
105 |     elif template.link:
106 |         line = f"{dist.canonical_name} @ {template.link.url}"
107 |     else:
108 |         line = f"{dist.canonical_name}=={dist.version}"
109 |     ireq = install_req_from_line(
110 |         line,
111 |         user_supplied=template.user_supplied,
112 |         comes_from=template.comes_from,
113 |         use_pep517=template.use_pep517,
114 |         isolated=template.isolated,
115 |         constraint=template.constraint,
116 |         global_options=template.global_options,
117 |         hash_options=template.hash_options,
118 |         config_settings=template.config_settings,
119 |     )
120 |     ireq.satisfied_by = dist
121 |     return ireq
122 | 
123 | 
124 | class _InstallRequirementBackedCandidate(Candidate):
125 |     """A candidate backed by an ``InstallRequirement``.
126 | 
127 |     This represents a package request with the target not being already
128 |     in the environment, and needs to be fetched and installed. The backing
129 |     ``InstallRequirement`` is responsible for most of the leg work; this
130 |     class exposes appropriate information to the resolver.
131 | 
132 |     :param link: The link passed to the ``InstallRequirement``. The backing
133 |         ``InstallRequirement`` will use this link to fetch the distribution.
134 |     :param source_link: The link this candidate "originates" from. This is
135 |         different from ``link`` when the link is found in the wheel cache.
136 |         ``link`` would point to the wheel cache, while this points to the
137 |         found remote link (e.g. from pypi.org).
138 |     """
139 | 
140 |     dist: BaseDistribution
141 |     is_installed = False
142 | 
143 |     def __init__(
144 |         self,
145 |         link: Link,
146 |         source_link: Link,
147 |         ireq: InstallRequirement,
148 |         factory: "Factory",
149 |         name: Optional[NormalizedName] = None,
150 |         version: Optional[Version] = None,
151 |     ) -> None:
152 |         self._link = link
153 |         self._source_link = source_link
154 |         self._factory = factory
155 |         self._ireq = ireq
156 |         self._name = name
157 |         self._version = version
158 |         self.dist = self._prepare()
159 |         self._hash: Optional[int] = None
160 | 
161 |     def __str__(self) -> str:
162 |         return f"{self.name} {self.version}"
163 | 
164 |     def __repr__(self) -> str:
165 |         return f"{self.__class__.__name__}({str(self._link)!r})"
166 | 
167 |     def __hash__(self) -> int:
168 |         if self._hash is not None:
169 |             return self._hash
170 | 
171 |         self._hash = hash((self.__class__, self._link))
172 |         return self._hash
173 | 
174 |     def __eq__(self, other: Any) -> bool:
175 |         if isinstance(other, self.__class__):
176 |             return links_equivalent(self._link, other._link)
177 |         return False
178 | 
179 |     @property
180 |     def source_link(self) -> Optional[Link]:
181 |         return self._source_link
182 | 
183 |     @property
184 |     def project_name(self) -> NormalizedName:
185 |         """The normalised name of the project the candidate refers to"""
186 |         if self._name is None:
187 |             self._name = self.dist.canonical_name
188 |         return self._name
189 | 
190 |     @property
191 |     def name(self) -> str:
192 |         return self.project_name
193 | 
194 |     @property
195 |     def version(self) -> Version:
196 |         if self._version is None:
197 |             self._version = self.dist.version
198 |         return self._version
199 | 
200 |     def format_for_error(self) -> str:
201 |         return (
202 |             f"{self.name} {self.version} "
203 |             f"(from {self._link.file_path if self._link.is_file else self._link})"
204 |         )
205 | 
206 |     def _prepare_distribution(self) -> BaseDistribution:
207 |         raise NotImplementedError("Override in subclass")
208 | 
209 |     def _check_metadata_consistency(self, dist: BaseDistribution) -> None:
210 |         """Check for consistency of project name and version of dist."""
211 |         if self._name is not None and self._name != dist.canonical_name:
212 |             raise MetadataInconsistent(
213 |                 self._ireq,
214 |                 "name",
215 |                 self._name,
216 |                 dist.canonical_name,
217 |             )
218 |         if self._version is not None and self._version != dist.version:
219 |             raise MetadataInconsistent(
220 |                 self._ireq,
221 |                 "version",
222 |                 str(self._version),
223 |                 str(dist.version),
224 |             )
225 |         # check dependencies are valid
226 |         # TODO performance: this means we iterate the dependencies at least twice,
227 |         # we may want to cache parsed Requires-Dist
228 |         try:
229 |             list(dist.iter_dependencies(list(dist.iter_provided_extras())))
230 |         except InvalidRequirement as e:
231 |             raise MetadataInvalid(self._ireq, str(e))
232 | 
233 |     def _prepare(self) -> BaseDistribution:
234 |         try:
235 |             dist = self._prepare_distribution()
236 |         except HashError as e:
237 |             # Provide HashError the underlying ireq that caused it. This
238 |             # provides context for the resulting error message to show the
239 |             # offending line to the user.
240 |             e.req = self._ireq
241 |             raise
242 |         except InstallationSubprocessError as exc:
243 |             # The output has been presented already, so don't duplicate it.
244 |             exc.context = "See above for output."
245 |             raise
246 | 
247 |         self._check_metadata_consistency(dist)
248 |         return dist
249 | 
250 |     def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
251 |         requires = self.dist.iter_dependencies() if with_requires else ()
252 |         for r in requires:
253 |             yield from self._factory.make_requirements_from_spec(str(r), self._ireq)
254 |         yield self._factory.make_requires_python_requirement(self.dist.requires_python)
255 | 
256 |     def get_install_requirement(self) -> Optional[InstallRequirement]:
257 |         return self._ireq
258 | 
259 | 
260 | class LinkCandidate(_InstallRequirementBackedCandidate):
261 |     is_editable = False
262 | 
263 |     def __init__(
264 |         self,
265 |         link: Link,
266 |         template: InstallRequirement,
267 |         factory: "Factory",
268 |         name: Optional[NormalizedName] = None,
269 |         version: Optional[Version] = None,
270 |     ) -> None:
271 |         source_link = link
272 |         cache_entry = factory.get_wheel_cache_entry(source_link, name)
273 |         if cache_entry is not None:
274 |             logger.debug("Using cached wheel link: %s", cache_entry.link)
275 |             link = cache_entry.link
276 |         ireq = make_install_req_from_link(link, template)
277 |         assert ireq.link == link
278 |         if ireq.link.is_wheel and not ireq.link.is_file:
279 |             wheel = Wheel(ireq.link.filename)
280 |             wheel_name = canonicalize_name(wheel.name)
281 |             assert name == wheel_name, f"{name!r} != {wheel_name!r} for wheel"
282 |             # Version may not be present for PEP 508 direct URLs
283 |             if version is not None:
284 |                 wheel_version = Version(wheel.version)
285 |                 assert (
286 |                     version == wheel_version
287 |                 ), f"{version!r} != {wheel_version!r} for wheel {name}"
288 | 
289 |         if cache_entry is not None:
290 |             assert ireq.link.is_wheel
291 |             assert ireq.link.is_file
292 |             if cache_entry.persistent and template.link is template.original_link:
293 |                 ireq.cached_wheel_source_link = source_link
294 |             if cache_entry.origin is not None:
295 |                 ireq.download_info = cache_entry.origin
296 |             else:
297 |                 # Legacy cache entry that does not have origin.json.
298 |                 # download_info may miss the archive_info.hashes field.
299 |                 ireq.download_info = direct_url_from_link(
300 |                     source_link, link_is_in_wheel_cache=cache_entry.persistent
301 |                 )
302 | 
303 |         super().__init__(
304 |             link=link,
305 |             source_link=source_link,
306 |             ireq=ireq,
307 |             factory=factory,
308 |             name=name,
309 |             version=version,
310 |         )
311 | 
312 |     def _prepare_distribution(self) -> BaseDistribution:
313 |         preparer = self._factory.preparer
314 |         return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True)
315 | 
316 | 
317 | class EditableCandidate(_InstallRequirementBackedCandidate):
318 |     is_editable = True
319 | 
320 |     def __init__(
321 |         self,
322 |         link: Link,
323 |         template: InstallRequirement,
324 |         factory: "Factory",
325 |         name: Optional[NormalizedName] = None,
326 |         version: Optional[Version] = None,
327 |     ) -> None:
328 |         super().__init__(
329 |             link=link,
330 |             source_link=link,
331 |             ireq=make_install_req_from_editable(link, template),
332 |             factory=factory,
333 |             name=name,
334 |             version=version,
335 |         )
336 | 
337 |     def _prepare_distribution(self) -> BaseDistribution:
338 |         return self._factory.preparer.prepare_editable_requirement(self._ireq)
339 | 
340 | 
341 | class AlreadyInstalledCandidate(Candidate):
342 |     is_installed = True
343 |     source_link = None
344 | 
345 |     def __init__(
346 |         self,
347 |         dist: BaseDistribution,
348 |         template: InstallRequirement,
349 |         factory: "Factory",
350 |     ) -> None:
351 |         self.dist = dist
352 |         self._ireq = _make_install_req_from_dist(dist, template)
353 |         self._factory = factory
354 |         self._version = None
355 | 
356 |         # This is just logging some messages, so we can do it eagerly.
357 |         # The returned dist would be exactly the same as self.dist because we
358 |         # set satisfied_by in _make_install_req_from_dist.
359 |         # TODO: Supply reason based on force_reinstall and upgrade_strategy.
360 |         skip_reason = "already satisfied"
361 |         factory.preparer.prepare_installed_requirement(self._ireq, skip_reason)
362 | 
363 |     def __str__(self) -> str:
364 |         return str(self.dist)
365 | 
366 |     def __repr__(self) -> str:
367 |         return f"{self.__class__.__name__}({self.dist!r})"
368 | 
369 |     def __eq__(self, other: object) -> bool:
370 |         if not isinstance(other, AlreadyInstalledCandidate):
371 |             return NotImplemented
372 |         return self.name == other.name and self.version == other.version
373 | 
374 |     def __hash__(self) -> int:
375 |         return hash((self.name, self.version))
376 | 
377 |     @property
378 |     def project_name(self) -> NormalizedName:
379 |         return self.dist.canonical_name
380 | 
381 |     @property
382 |     def name(self) -> str:
383 |         return self.project_name
384 | 
385 |     @property
386 |     def version(self) -> Version:
387 |         if self._version is None:
388 |             self._version = self.dist.version
389 |         return self._version
390 | 
391 |     @property
392 |     def is_editable(self) -> bool:
393 |         return self.dist.editable
394 | 
395 |     def format_for_error(self) -> str:
396 |         return f"{self.name} {self.version} (Installed)"
397 | 
398 |     def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
399 |         if not with_requires:
400 |             return
401 |         for r in self.dist.iter_dependencies():
402 |             yield from self._factory.make_requirements_from_spec(str(r), self._ireq)
403 | 
404 |     def get_install_requirement(self) -> Optional[InstallRequirement]:
405 |         return None
406 | 
407 | 
408 | class ExtrasCandidate(Candidate):
409 |     """A candidate that has 'extras', indicating additional dependencies.
410 | 
411 |     Requirements can be for a project with dependencies, something like
412 |     foo[extra].  The extras don't affect the project/version being installed
413 |     directly, but indicate that we need additional dependencies. We model that
414 |     by having an artificial ExtrasCandidate that wraps the "base" candidate.
415 | 
416 |     The ExtrasCandidate differs from the base in the following ways:
417 | 
418 |     1. It has a unique name, of the form foo[extra]. This causes the resolver
419 |        to treat it as a separate node in the dependency graph.
420 |     2. When we're getting the candidate's dependencies,
421 |        a) We specify that we want the extra dependencies as well.
422 |        b) We add a dependency on the base candidate.
423 |           See below for why this is needed.
424 |     3. We return None for the underlying InstallRequirement, as the base
425 |        candidate will provide it, and we don't want to end up with duplicates.
426 | 
427 |     The dependency on the base candidate is needed so that the resolver can't
428 |     decide that it should recommend foo[extra1] version 1.0 and foo[extra2]
429 |     version 2.0. Having those candidates depend on foo=1.0 and foo=2.0
430 |     respectively forces the resolver to recognise that this is a conflict.
431 |     """
432 | 
433 |     def __init__(
434 |         self,
435 |         base: BaseCandidate,
436 |         extras: FrozenSet[str],
437 |         *,
438 |         comes_from: Optional[InstallRequirement] = None,
439 |     ) -> None:
440 |         """
441 |         :param comes_from: the InstallRequirement that led to this candidate if it
442 |             differs from the base's InstallRequirement. This will often be the
443 |             case in the sense that this candidate's requirement has the extras
444 |             while the base's does not. Unlike the InstallRequirement backed
445 |             candidates, this requirement is used solely for reporting purposes,
446 |             it does not do any leg work.
447 |         """
448 |         self.base = base
449 |         self.extras = frozenset(canonicalize_name(e) for e in extras)
450 |         self._comes_from = comes_from if comes_from is not None else self.base._ireq
451 | 
452 |     def __str__(self) -> str:
453 |         name, rest = str(self.base).split(" ", 1)
454 |         return "{}[{}] {}".format(name, ",".join(self.extras), rest)
455 | 
456 |     def __repr__(self) -> str:
457 |         return f"{self.__class__.__name__}(base={self.base!r}, extras={self.extras!r})"
458 | 
459 |     def __hash__(self) -> int:
460 |         return hash((self.base, self.extras))
461 | 
462 |     def __eq__(self, other: Any) -> bool:
463 |         if isinstance(other, self.__class__):
464 |             return self.base == other.base and self.extras == other.extras
465 |         return False
466 | 
467 |     @property
468 |     def project_name(self) -> NormalizedName:
469 |         return self.base.project_name
470 | 
471 |     @property
472 |     def name(self) -> str:
473 |         """The normalised name of the project the candidate refers to"""
474 |         return format_name(self.base.project_name, self.extras)
475 | 
476 |     @property
477 |     def version(self) -> Version:
478 |         return self.base.version
479 | 
480 |     def format_for_error(self) -> str:
481 |         return "{} [{}]".format(
482 |             self.base.format_for_error(), ", ".join(sorted(self.extras))
483 |         )
484 | 
485 |     @property
486 |     def is_installed(self) -> bool:
487 |         return self.base.is_installed
488 | 
489 |     @property
490 |     def is_editable(self) -> bool:
491 |         return self.base.is_editable
492 | 
493 |     @property
494 |     def source_link(self) -> Optional[Link]:
495 |         return self.base.source_link
496 | 
497 |     def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
498 |         factory = self.base._factory
499 | 
500 |         # Add a dependency on the exact base
501 |         # (See note 2b in the class docstring)
502 |         yield factory.make_requirement_from_candidate(self.base)
503 |         if not with_requires:
504 |             return
505 | 
506 |         # The user may have specified extras that the candidate doesn't
507 |         # support. We ignore any unsupported extras here.
508 |         valid_extras = self.extras.intersection(self.base.dist.iter_provided_extras())
509 |         invalid_extras = self.extras.difference(self.base.dist.iter_provided_extras())
510 |         for extra in sorted(invalid_extras):
511 |             logger.warning(
512 |                 "%s %s does not provide the extra '%s'",
513 |                 self.base.name,
514 |                 self.version,
515 |                 extra,
516 |             )
517 | 
518 |         for r in self.base.dist.iter_dependencies(valid_extras):
519 |             yield from factory.make_requirements_from_spec(
520 |                 str(r),
521 |                 self._comes_from,
522 |                 valid_extras,
523 |             )
524 | 
525 |     def get_install_requirement(self) -> Optional[InstallRequirement]:
526 |         # We don't return anything here, because we always
527 |         # depend on the base candidate, and we'll get the
528 |         # install requirement from that.
529 |         return None
530 | 
531 | 
532 | class RequiresPythonCandidate(Candidate):
533 |     is_installed = False
534 |     source_link = None
535 | 
536 |     def __init__(self, py_version_info: Optional[Tuple[int, ...]]) -> None:
537 |         if py_version_info is not None:
538 |             version_info = normalize_version_info(py_version_info)
539 |         else:
540 |             version_info = sys.version_info[:3]
541 |         self._version = Version(".".join(str(c) for c in version_info))
542 | 
543 |     # We don't need to implement __eq__() and __ne__() since there is always
544 |     # only one RequiresPythonCandidate in a resolution, i.e. the host Python.
545 |     # The built-in object.__eq__() and object.__ne__() do exactly what we want.
546 | 
547 |     def __str__(self) -> str:
548 |         return f"Python {self._version}"
549 | 
550 |     @property
551 |     def project_name(self) -> NormalizedName:
552 |         return REQUIRES_PYTHON_IDENTIFIER
553 | 
554 |     @property
555 |     def name(self) -> str:
556 |         return REQUIRES_PYTHON_IDENTIFIER
557 | 
558 |     @property
559 |     def version(self) -> Version:
560 |         return self._version
561 | 
562 |     def format_for_error(self) -> str:
563 |         return f"Python {self.version}"
564 | 
565 |     def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
566 |         return ()
567 | 
568 |     def get_install_requirement(self) -> Optional[InstallRequirement]:
569 |         return None
570 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/bs4/tests/test_soup.py:
--------------------------------------------------------------------------------

```python
  1 | # -*- coding: utf-8 -*-
  2 | """Tests of Beautiful Soup as a whole."""
  3 | 
  4 | from pdb import set_trace
  5 | import logging
  6 | import os
  7 | import pickle
  8 | import pytest
  9 | import sys
 10 | import tempfile
 11 | 
 12 | from bs4 import (
 13 |     BeautifulSoup,
 14 |     BeautifulStoneSoup,
 15 |     GuessedAtParserWarning,
 16 |     MarkupResemblesLocatorWarning,
 17 |     dammit,
 18 | )
 19 | from bs4.builder import (
 20 |     builder_registry,
 21 |     TreeBuilder,
 22 |     ParserRejectedMarkup,
 23 | )
 24 | from bs4.element import (
 25 |     Comment,
 26 |     SoupStrainer,
 27 |     PYTHON_SPECIFIC_ENCODINGS,
 28 |     Tag,
 29 |     NavigableString,
 30 | )
 31 | 
 32 | from . import (
 33 |     default_builder,
 34 |     LXML_PRESENT,
 35 |     SoupTest,
 36 | )
 37 | import warnings
 38 |     
 39 | class TestConstructor(SoupTest):
 40 | 
 41 |     def test_short_unicode_input(self):
 42 |         data = "<h1>éé</h1>"
 43 |         soup = self.soup(data)
 44 |         assert "éé" == soup.h1.string
 45 | 
 46 |     def test_embedded_null(self):
 47 |         data = "<h1>foo\0bar</h1>"
 48 |         soup = self.soup(data)
 49 |         assert "foo\0bar" == soup.h1.string
 50 | 
 51 |     def test_exclude_encodings(self):
 52 |         utf8_data = "Räksmörgås".encode("utf-8")
 53 |         soup = self.soup(utf8_data, exclude_encodings=["utf-8"])
 54 |         assert "windows-1252" == soup.original_encoding
 55 | 
 56 |     def test_custom_builder_class(self):
 57 |         # Verify that you can pass in a custom Builder class and
 58 |         # it'll be instantiated with the appropriate keyword arguments.
 59 |         class Mock(object):
 60 |             def __init__(self, **kwargs):
 61 |                 self.called_with = kwargs
 62 |                 self.is_xml = True
 63 |                 self.store_line_numbers = False
 64 |                 self.cdata_list_attributes = []
 65 |                 self.preserve_whitespace_tags = []
 66 |                 self.string_containers = {}
 67 |             def initialize_soup(self, soup):
 68 |                 pass
 69 |             def feed(self, markup):
 70 |                 self.fed = markup
 71 |             def reset(self):
 72 |                 pass
 73 |             def ignore(self, ignore):
 74 |                 pass
 75 |             set_up_substitutions = can_be_empty_element = ignore
 76 |             def prepare_markup(self, *args, **kwargs):
 77 |                 yield "prepared markup", "original encoding", "declared encoding", "contains replacement characters"
 78 |                 
 79 |         kwargs = dict(
 80 |             var="value",
 81 |             # This is a deprecated BS3-era keyword argument, which
 82 |             # will be stripped out.
 83 |             convertEntities=True,
 84 |         )
 85 |         with warnings.catch_warnings(record=True):
 86 |             soup = BeautifulSoup('', builder=Mock, **kwargs)
 87 |         assert isinstance(soup.builder, Mock)
 88 |         assert dict(var="value") == soup.builder.called_with
 89 |         assert "prepared markup" == soup.builder.fed
 90 |         
 91 |         # You can also instantiate the TreeBuilder yourself. In this
 92 |         # case, that specific object is used and any keyword arguments
 93 |         # to the BeautifulSoup constructor are ignored.
 94 |         builder = Mock(**kwargs)
 95 |         with warnings.catch_warnings(record=True) as w:
 96 |             soup = BeautifulSoup(
 97 |                 '', builder=builder, ignored_value=True,
 98 |             )
 99 |         msg = str(w[0].message)
100 |         assert msg.startswith("Keyword arguments to the BeautifulSoup constructor will be ignored.")
101 |         assert builder == soup.builder
102 |         assert kwargs == builder.called_with
103 | 
104 |     def test_parser_markup_rejection(self):
105 |         # If markup is completely rejected by the parser, an
106 |         # explanatory ParserRejectedMarkup exception is raised.
107 |         class Mock(TreeBuilder):
108 |             def feed(self, *args, **kwargs):
109 |                 raise ParserRejectedMarkup("Nope.")
110 | 
111 |         def prepare_markup(self, *args, **kwargs):
112 |             # We're going to try two different ways of preparing this markup,
113 |             # but feed() will reject both of them.
114 |             yield markup, None, None, False
115 |             yield markup, None, None, False
116 |             
117 | 
118 |         import re
119 |         with pytest.raises(ParserRejectedMarkup) as exc_info:
120 |             BeautifulSoup('', builder=Mock)
121 |         assert "The markup you provided was rejected by the parser. Trying a different parser or a different encoding may help." in str(exc_info.value)
122 |         
123 |     def test_cdata_list_attributes(self):
124 |         # Most attribute values are represented as scalars, but the
125 |         # HTML standard says that some attributes, like 'class' have
126 |         # space-separated lists as values.
127 |         markup = '<a id=" an id " class=" a class "></a>'
128 |         soup = self.soup(markup)
129 | 
130 |         # Note that the spaces are stripped for 'class' but not for 'id'.
131 |         a = soup.a
132 |         assert " an id " == a['id']
133 |         assert ["a", "class"] == a['class']
134 | 
135 |         # TreeBuilder takes an argument called 'multi_valued_attributes'  which lets
136 |         # you customize or disable this. As always, you can customize the TreeBuilder
137 |         # by passing in a keyword argument to the BeautifulSoup constructor.
138 |         soup = self.soup(markup, builder=default_builder, multi_valued_attributes=None)
139 |         assert " a class " == soup.a['class']
140 | 
141 |         # Here are two ways of saying that `id` is a multi-valued
142 |         # attribute in this context, but 'class' is not.
143 |         for switcheroo in ({'*': 'id'}, {'a': 'id'}):
144 |             with warnings.catch_warnings(record=True) as w:
145 |                 # This will create a warning about not explicitly
146 |                 # specifying a parser, but we'll ignore it.
147 |                 soup = self.soup(markup, builder=None, multi_valued_attributes=switcheroo)
148 |             a = soup.a
149 |             assert ["an", "id"] == a['id']
150 |             assert " a class " == a['class']
151 | 
152 |     def test_replacement_classes(self):
153 |         # Test the ability to pass in replacements for element classes
154 |         # which will be used when building the tree.
155 |         class TagPlus(Tag):
156 |             pass
157 | 
158 |         class StringPlus(NavigableString):
159 |             pass
160 | 
161 |         class CommentPlus(Comment):
162 |             pass
163 |         
164 |         soup = self.soup(
165 |             "<a><b>foo</b>bar</a><!--whee-->",
166 |             element_classes = {
167 |                 Tag: TagPlus,
168 |                 NavigableString: StringPlus,
169 |                 Comment: CommentPlus,
170 |             }
171 |         )
172 | 
173 |         # The tree was built with TagPlus, StringPlus, and CommentPlus objects,
174 |         # rather than Tag, String, and Comment objects.
175 |         assert all(
176 |             isinstance(x, (TagPlus, StringPlus, CommentPlus))
177 |             for x in soup.recursiveChildGenerator()
178 |         )
179 | 
180 |     def test_alternate_string_containers(self):
181 |         # Test the ability to customize the string containers for
182 |         # different types of tags.
183 |         class PString(NavigableString):
184 |             pass
185 | 
186 |         class BString(NavigableString):
187 |             pass
188 | 
189 |         soup = self.soup(
190 |             "<div>Hello.<p>Here is <b>some <i>bolded</i></b> text",
191 |             string_containers = {
192 |                 'b': BString,
193 |                 'p': PString,
194 |             }
195 |         )
196 | 
197 |         # The string before the <p> tag is a regular NavigableString.
198 |         assert isinstance(soup.div.contents[0], NavigableString)
199 |         
200 |         # The string inside the <p> tag, but not inside the <i> tag,
201 |         # is a PString.
202 |         assert isinstance(soup.p.contents[0], PString)
203 | 
204 |         # Every string inside the <b> tag is a BString, even the one that
205 |         # was also inside an <i> tag.
206 |         for s in soup.b.strings:
207 |             assert isinstance(s, BString)
208 | 
209 |         # Now that parsing was complete, the string_container_stack
210 |         # (where this information was kept) has been cleared out.
211 |         assert [] == soup.string_container_stack
212 | 
213 | 
214 | class TestOutput(SoupTest):
215 | 
216 |     @pytest.mark.parametrize(
217 |         "eventual_encoding,actual_encoding", [
218 |             ("utf-8", "utf-8"),
219 |             ("utf-16", "utf-16"),
220 |         ]
221 |     )
222 |     def test_decode_xml_declaration(self, eventual_encoding, actual_encoding):
223 |         # Most of the time, calling decode() on an XML document will
224 |         # give you a document declaration that mentions the encoding
225 |         # you intend to use when encoding the document as a
226 |         # bytestring.
227 |         soup = self.soup("<tag></tag>")
228 |         soup.is_xml = True
229 |         assert (f'<?xml version="1.0" encoding="{actual_encoding}"?>\n<tag></tag>'
230 |                 == soup.decode(eventual_encoding=eventual_encoding))
231 | 
232 |     @pytest.mark.parametrize(
233 |         "eventual_encoding", [x for x in PYTHON_SPECIFIC_ENCODINGS] + [None]
234 |     )
235 |     def test_decode_xml_declaration_with_missing_or_python_internal_eventual_encoding(self, eventual_encoding):
236 |         # But if you pass a Python internal encoding into decode(), or
237 |         # omit the eventual_encoding altogether, the document
238 |         # declaration won't mention any particular encoding.
239 |         soup = BeautifulSoup("<tag></tag>", "html.parser")
240 |         soup.is_xml = True
241 |         assert (f'<?xml version="1.0"?>\n<tag></tag>'
242 |                 == soup.decode(eventual_encoding=eventual_encoding))
243 | 
244 |     def test(self):
245 |         # BeautifulSoup subclasses Tag and extends the decode() method.
246 |         # Make sure the other Tag methods which call decode() call
247 |         # it correctly.
248 |         soup = self.soup("<tag></tag>")
249 |         assert b"<tag></tag>" == soup.encode(encoding="utf-8")
250 |         assert b"<tag></tag>" == soup.encode_contents(encoding="utf-8")
251 |         assert "<tag></tag>" == soup.decode_contents()
252 |         assert "<tag>\n</tag>\n" == soup.prettify()
253 | 
254 |         
255 | class TestWarnings(SoupTest):
256 |     # Note that some of the tests in this class create BeautifulSoup
257 |     # objects directly rather than using self.soup(). That's
258 |     # because SoupTest.soup is defined in a different file,
259 |     # which will throw off the assertion in _assert_warning
260 |     # that the code that triggered the warning is in the same
261 |     # file as the test.
262 | 
263 |     def _assert_warning(self, warnings, cls):
264 |         for w in warnings:
265 |             if isinstance(w.message, cls):
266 |                 assert w.filename == __file__
267 |                 return w
268 |         raise Exception("%s warning not found in %r" % (cls, warnings))
269 |     
270 |     def _assert_no_parser_specified(self, w):
271 |         warning = self._assert_warning(w, GuessedAtParserWarning)
272 |         message = str(warning.message)
273 |         assert message.startswith(BeautifulSoup.NO_PARSER_SPECIFIED_WARNING[:60])
274 | 
275 |     def test_warning_if_no_parser_specified(self):
276 |         with warnings.catch_warnings(record=True) as w:
277 |             soup = BeautifulSoup("<a><b></b></a>")
278 |         self._assert_no_parser_specified(w)
279 | 
280 |     def test_warning_if_parser_specified_too_vague(self):
281 |         with warnings.catch_warnings(record=True) as w:
282 |             soup = BeautifulSoup("<a><b></b></a>", "html")
283 |         self._assert_no_parser_specified(w)
284 | 
285 |     def test_no_warning_if_explicit_parser_specified(self):
286 |         with warnings.catch_warnings(record=True) as w:
287 |             soup = self.soup("<a><b></b></a>")
288 |         assert [] == w
289 | 
290 |     def test_parseOnlyThese_renamed_to_parse_only(self):
291 |         with warnings.catch_warnings(record=True) as w:
292 |             soup = BeautifulSoup(
293 |                 "<a><b></b></a>", "html.parser",
294 |                 parseOnlyThese=SoupStrainer("b"),
295 |             )
296 |         warning = self._assert_warning(w, DeprecationWarning)
297 |         msg = str(warning.message)
298 |         assert "parseOnlyThese" in msg
299 |         assert "parse_only" in msg
300 |         assert b"<b></b>" == soup.encode()
301 | 
302 |     def test_fromEncoding_renamed_to_from_encoding(self):
303 |         with warnings.catch_warnings(record=True) as w:
304 |             utf8 = b"\xc3\xa9"
305 |             soup = BeautifulSoup(
306 |                 utf8, "html.parser", fromEncoding="utf8"
307 |             )
308 |         warning = self._assert_warning(w, DeprecationWarning)
309 |         msg = str(warning.message)
310 |         assert "fromEncoding" in msg
311 |         assert "from_encoding" in msg
312 |         assert "utf8" == soup.original_encoding
313 | 
314 |     def test_unrecognized_keyword_argument(self):
315 |         with pytest.raises(TypeError):
316 |             self.soup("<a>", no_such_argument=True)
317 | 
318 |     @pytest.mark.parametrize(
319 |         "extension",
320 |         ['markup.html', 'markup.htm', 'markup.HTML', 'markup.txt',
321 |          'markup.xhtml', 'markup.xml', "/home/user/file", "c:\\user\file"]
322 |     )
323 |     def test_resembles_filename_warning(self, extension):
324 |         # A warning is issued if the "markup" looks like the name of
325 |         # an HTML or text file, or a full path to a file on disk.
326 |         with warnings.catch_warnings(record=True) as w:
327 |             soup = BeautifulSoup("markup" + extension, "html.parser")
328 |             warning = self._assert_warning(w, MarkupResemblesLocatorWarning)
329 |             assert "looks more like a filename" in str(warning.message)
330 | 
331 |     @pytest.mark.parametrize(
332 |         "extension",
333 |         ['markuphtml', 'markup.com', '', 'markup.js']
334 |     )
335 |     def test_resembles_filename_no_warning(self, extension):
336 |         # The 'looks more like a filename' warning is not issued if
337 |         # the markup looks like a bare string, a domain name, or a
338 |         # file that's not an HTML file.
339 |         with warnings.catch_warnings(record=True) as w:
340 |             soup = self.soup("markup" + extension)
341 |         assert [] == w
342 | 
343 |     def test_url_warning_with_bytes_url(self):
344 |         url = b"http://www.crummybytes.com/"
345 |         with warnings.catch_warnings(record=True) as warning_list:
346 |             soup = BeautifulSoup(url, "html.parser")
347 |         warning = self._assert_warning(
348 |             warning_list, MarkupResemblesLocatorWarning
349 |         )
350 |         assert "looks more like a URL" in str(warning.message)
351 |         assert url not in str(warning.message).encode("utf8")
352 |         
353 |     def test_url_warning_with_unicode_url(self):
354 |         url = "http://www.crummyunicode.com/"
355 |         with warnings.catch_warnings(record=True) as warning_list:
356 |             # note - this url must differ from the bytes one otherwise
357 |             # python's warnings system swallows the second warning
358 |             soup = BeautifulSoup(url, "html.parser")
359 |         warning = self._assert_warning(
360 |             warning_list, MarkupResemblesLocatorWarning
361 |         )
362 |         assert "looks more like a URL" in str(warning.message)
363 |         assert url not in str(warning.message)
364 | 
365 |     def test_url_warning_with_bytes_and_space(self):
366 |         # Here the markup contains something besides a URL, so no warning
367 |         # is issued.
368 |         with warnings.catch_warnings(record=True) as warning_list:
369 |             soup = self.soup(b"http://www.crummybytes.com/ is great")
370 |         assert not any("looks more like a URL" in str(w.message) 
371 |                        for w in warning_list)
372 | 
373 |     def test_url_warning_with_unicode_and_space(self):
374 |         with warnings.catch_warnings(record=True) as warning_list:
375 |             soup = self.soup("http://www.crummyunicode.com/ is great")
376 |         assert not any("looks more like a URL" in str(w.message) 
377 |                        for w in warning_list)
378 | 
379 | 
380 | class TestSelectiveParsing(SoupTest):
381 | 
382 |     def test_parse_with_soupstrainer(self):
383 |         markup = "No<b>Yes</b><a>No<b>Yes <c>Yes</c></b>"
384 |         strainer = SoupStrainer("b")
385 |         soup = self.soup(markup, parse_only=strainer)
386 |         assert soup.encode() == b"<b>Yes</b><b>Yes <c>Yes</c></b>"
387 | 
388 |         
389 | class TestNewTag(SoupTest):
390 |     """Test the BeautifulSoup.new_tag() method."""
391 |     def test_new_tag(self):
392 |         soup = self.soup("")
393 |         new_tag = soup.new_tag("foo", bar="baz", attrs={"name": "a name"})
394 |         assert isinstance(new_tag, Tag)
395 |         assert "foo" == new_tag.name
396 |         assert dict(bar="baz", name="a name") == new_tag.attrs
397 |         assert None == new_tag.parent
398 | 
399 |     @pytest.mark.skipif(
400 |         not LXML_PRESENT,
401 |         reason="lxml not installed, cannot parse XML document"
402 |     )
403 |     def test_xml_tag_inherits_self_closing_rules_from_builder(self):
404 |         xml_soup = BeautifulSoup("", "xml")
405 |         xml_br = xml_soup.new_tag("br")
406 |         xml_p = xml_soup.new_tag("p")
407 | 
408 |         # Both the <br> and <p> tag are empty-element, just because
409 |         # they have no contents.
410 |         assert b"<br/>" == xml_br.encode()
411 |         assert b"<p/>" == xml_p.encode()
412 | 
413 |     def test_tag_inherits_self_closing_rules_from_builder(self):
414 |         html_soup = BeautifulSoup("", "html.parser")
415 |         html_br = html_soup.new_tag("br")
416 |         html_p = html_soup.new_tag("p")
417 | 
418 |         # The HTML builder users HTML's rules about which tags are
419 |         # empty-element tags, and the new tags reflect these rules.
420 |         assert b"<br/>" == html_br.encode()
421 |         assert b"<p></p>" == html_p.encode()
422 | 
423 | class TestNewString(SoupTest):
424 |     """Test the BeautifulSoup.new_string() method."""
425 |     def test_new_string_creates_navigablestring(self):
426 |         soup = self.soup("")
427 |         s = soup.new_string("foo")
428 |         assert "foo" == s
429 |         assert isinstance(s, NavigableString)
430 | 
431 |     def test_new_string_can_create_navigablestring_subclass(self):
432 |         soup = self.soup("")
433 |         s = soup.new_string("foo", Comment)
434 |         assert "foo" == s
435 |         assert isinstance(s, Comment)
436 | 
437 | 
438 | class TestPickle(SoupTest):
439 |    # Test our ability to pickle the BeautifulSoup object itself.
440 | 
441 |     def test_normal_pickle(self):
442 |         soup = self.soup("<a>some markup</a>")
443 |         pickled = pickle.dumps(soup)
444 |         unpickled = pickle.loads(pickled)
445 |         assert "some markup" == unpickled.a.string
446 |         
447 |     def test_pickle_with_no_builder(self):
448 |         # We had a bug that prevented pickling from working if
449 |         # the builder wasn't set.
450 |         soup = self.soup("some markup")
451 |         soup.builder = None
452 |         pickled = pickle.dumps(soup)
453 |         unpickled = pickle.loads(pickled)
454 |         assert "some markup" == unpickled.string
455 | 
456 | class TestEncodingConversion(SoupTest):
457 |     # Test Beautiful Soup's ability to decode and encode from various
458 |     # encodings.
459 | 
460 |     def setup_method(self):
461 |         self.unicode_data = '<html><head><meta charset="utf-8"/></head><body><foo>Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!</foo></body></html>'
462 |         self.utf8_data = self.unicode_data.encode("utf-8")
463 |         # Just so you know what it looks like.
464 |         assert self.utf8_data == b'<html><head><meta charset="utf-8"/></head><body><foo>Sacr\xc3\xa9 bleu!</foo></body></html>'
465 | 
466 |     def test_ascii_in_unicode_out(self):
467 |         # ASCII input is converted to Unicode. The original_encoding
468 |         # attribute is set to 'utf-8', a superset of ASCII.
469 |         chardet = dammit.chardet_dammit
470 |         logging.disable(logging.WARNING)
471 |         try:
472 |             def noop(str):
473 |                 return None
474 |             # Disable chardet, which will realize that the ASCII is ASCII.
475 |             dammit.chardet_dammit = noop
476 |             ascii = b"<foo>a</foo>"
477 |             soup_from_ascii = self.soup(ascii)
478 |             unicode_output = soup_from_ascii.decode()
479 |             assert isinstance(unicode_output, str)
480 |             assert unicode_output == self.document_for(ascii.decode())
481 |             assert soup_from_ascii.original_encoding.lower() == "utf-8"
482 |         finally:
483 |             logging.disable(logging.NOTSET)
484 |             dammit.chardet_dammit = chardet
485 | 
486 |     def test_unicode_in_unicode_out(self):
487 |         # Unicode input is left alone. The original_encoding attribute
488 |         # is not set.
489 |         soup_from_unicode = self.soup(self.unicode_data)
490 |         assert soup_from_unicode.decode() == self.unicode_data
491 |         assert soup_from_unicode.foo.string == 'Sacr\xe9 bleu!'
492 |         assert soup_from_unicode.original_encoding == None
493 | 
494 |     def test_utf8_in_unicode_out(self):
495 |         # UTF-8 input is converted to Unicode. The original_encoding
496 |         # attribute is set.
497 |         soup_from_utf8 = self.soup(self.utf8_data)
498 |         assert soup_from_utf8.decode() == self.unicode_data
499 |         assert soup_from_utf8.foo.string == 'Sacr\xe9 bleu!'
500 | 
501 |     def test_utf8_out(self):
502 |         # The internal data structures can be encoded as UTF-8.
503 |         soup_from_unicode = self.soup(self.unicode_data)
504 |         assert soup_from_unicode.encode('utf-8') == self.utf8_data
505 | 
```
Page 67/168FirstPrevNextLast