#
tokens: 47600/50000 1/808 files (page 141/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 141 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/bs4/tests/test_tree.py:
--------------------------------------------------------------------------------

```python
   1 | # -*- coding: utf-8 -*-
   2 | """Tests for Beautiful Soup's tree traversal methods.
   3 | 
   4 | The tree traversal methods are the main advantage of using Beautiful
   5 | Soup over just using a parser.
   6 | 
   7 | Different parsers will build different Beautiful Soup trees given the
   8 | same markup, but all Beautiful Soup trees can be traversed with the
   9 | methods tested here.
  10 | """
  11 | 
  12 | from pdb import set_trace
  13 | import pytest
  14 | import re
  15 | import warnings
  16 | from bs4 import BeautifulSoup
  17 | from bs4.builder import (
  18 |     builder_registry,
  19 |     HTMLParserTreeBuilder,
  20 | )
  21 | from bs4.element import (
  22 |     CData,
  23 |     Comment,
  24 |     Declaration,
  25 |     Doctype,
  26 |     Formatter,
  27 |     NavigableString,
  28 |     Script,
  29 |     SoupStrainer,
  30 |     Stylesheet,
  31 |     Tag,
  32 |     TemplateString,
  33 | )
  34 | from . import (
  35 |     SoupTest,
  36 | )
  37 | 
  38 | class TestFind(SoupTest):
  39 |     """Basic tests of the find() method.
  40 | 
  41 |     find() just calls find_all() with limit=1, so it's not tested all
  42 |     that thouroughly here.
  43 |     """
  44 | 
  45 |     def test_find_tag(self):
  46 |         soup = self.soup("<a>1</a><b>2</b><a>3</a><b>4</b>")
  47 |         assert soup.find("b").string == "2"
  48 | 
  49 |     def test_unicode_text_find(self):
  50 |         soup = self.soup('<h1>Räksmörgås</h1>')
  51 |         assert soup.find(string='Räksmörgås') == 'Räksmörgås'
  52 | 
  53 |     def test_unicode_attribute_find(self):
  54 |         soup = self.soup('<h1 id="Räksmörgås">here it is</h1>')
  55 |         str(soup)
  56 |         assert "here it is" == soup.find(id='Räksmörgås').text
  57 | 
  58 | 
  59 |     def test_find_everything(self):
  60 |         """Test an optimization that finds all tags."""
  61 |         soup = self.soup("<a>foo</a><b>bar</b>")
  62 |         assert 2 == len(soup.find_all())
  63 | 
  64 |     def test_find_everything_with_name(self):
  65 |         """Test an optimization that finds all tags with a given name."""
  66 |         soup = self.soup("<a>foo</a><b>bar</b><a>baz</a>")
  67 |         assert 2 == len(soup.find_all('a'))
  68 | 
  69 | class TestFindAll(SoupTest):
  70 |     """Basic tests of the find_all() method."""
  71 | 
  72 |     def test_find_all_text_nodes(self):
  73 |         """You can search the tree for text nodes."""
  74 |         soup = self.soup("<html>Foo<b>bar</b>\xbb</html>")
  75 |         # Exact match.
  76 |         assert soup.find_all(string="bar") == ["bar"]
  77 | 
  78 |        
  79 |         # Match any of a number of strings.
  80 |         assert soup.find_all(string=["Foo", "bar"]) == ["Foo", "bar"]
  81 |         # Match a regular expression.
  82 |         assert soup.find_all(string=re.compile('.*')) == ["Foo", "bar", '\xbb']
  83 |         # Match anything.
  84 |         assert soup.find_all(string=True) == ["Foo", "bar", '\xbb']
  85 | 
  86 |     def test_find_all_limit(self):
  87 |         """You can limit the number of items returned by find_all."""
  88 |         soup = self.soup("<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a>")
  89 |         self.assert_selects(soup.find_all('a', limit=3), ["1", "2", "3"])
  90 |         self.assert_selects(soup.find_all('a', limit=1), ["1"])
  91 |         self.assert_selects(
  92 |             soup.find_all('a', limit=10), ["1", "2", "3", "4", "5"])
  93 | 
  94 |         # A limit of 0 means no limit.
  95 |         self.assert_selects(
  96 |             soup.find_all('a', limit=0), ["1", "2", "3", "4", "5"])
  97 | 
  98 |     def test_calling_a_tag_is_calling_findall(self):
  99 |         soup = self.soup("<a>1</a><b>2<a id='foo'>3</a></b>")
 100 |         self.assert_selects(soup('a', limit=1), ["1"])
 101 |         self.assert_selects(soup.b(id="foo"), ["3"])
 102 | 
 103 |     def test_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursion(self):
 104 |         soup = self.soup("<a></a>")
 105 |         # Create a self-referential list.
 106 |         l = []
 107 |         l.append(l)
 108 | 
 109 |         # Without special code in _normalize_search_value, this would cause infinite
 110 |         # recursion.
 111 |         assert [] == soup.find_all(l)
 112 | 
 113 |     def test_find_all_resultset(self):
 114 |         """All find_all calls return a ResultSet"""
 115 |         soup = self.soup("<a></a>")
 116 |         result = soup.find_all("a")
 117 |         assert hasattr(result, "source")
 118 | 
 119 |         result = soup.find_all(True)
 120 |         assert hasattr(result, "source")
 121 | 
 122 |         result = soup.find_all(string="foo")
 123 |         assert hasattr(result, "source")
 124 | 
 125 | 
 126 | class TestFindAllBasicNamespaces(SoupTest):
 127 | 
 128 |     def test_find_by_namespaced_name(self):
 129 |         soup = self.soup('<mathml:msqrt>4</mathml:msqrt><a svg:fill="red">')
 130 |         assert "4" == soup.find("mathml:msqrt").string
 131 |         assert "a" == soup.find(attrs= { "svg:fill" : "red" }).name
 132 | 
 133 | 
 134 | class TestFindAllByName(SoupTest):
 135 |     """Test ways of finding tags by tag name."""
 136 | 
 137 |     def setup_method(self):
 138 |         self.tree =  self.soup("""<a>First tag.</a>
 139 |                                   <b>Second tag.</b>
 140 |                                   <c>Third <a>Nested tag.</a> tag.</c>""")
 141 | 
 142 |     def test_find_all_by_tag_name(self):
 143 |         # Find all the <a> tags.
 144 |         self.assert_selects(
 145 |             self.tree.find_all('a'), ['First tag.', 'Nested tag.'])
 146 | 
 147 |     def test_find_all_by_name_and_text(self):
 148 |         self.assert_selects(
 149 |             self.tree.find_all('a', string='First tag.'), ['First tag.'])
 150 | 
 151 |         self.assert_selects(
 152 |             self.tree.find_all('a', string=True), ['First tag.', 'Nested tag.'])
 153 | 
 154 |         self.assert_selects(
 155 |             self.tree.find_all('a', string=re.compile("tag")),
 156 |             ['First tag.', 'Nested tag.'])
 157 | 
 158 | 
 159 |     def test_find_all_on_non_root_element(self):
 160 |         # You can call find_all on any node, not just the root.
 161 |         self.assert_selects(self.tree.c.find_all('a'), ['Nested tag.'])
 162 | 
 163 |     def test_calling_element_invokes_find_all(self):
 164 |         self.assert_selects(self.tree('a'), ['First tag.', 'Nested tag.'])
 165 | 
 166 |     def test_find_all_by_tag_strainer(self):
 167 |         self.assert_selects(
 168 |             self.tree.find_all(SoupStrainer('a')),
 169 |             ['First tag.', 'Nested tag.'])
 170 | 
 171 |     def test_find_all_by_tag_names(self):
 172 |         self.assert_selects(
 173 |             self.tree.find_all(['a', 'b']),
 174 |             ['First tag.', 'Second tag.', 'Nested tag.'])
 175 | 
 176 |     def test_find_all_by_tag_dict(self):
 177 |         self.assert_selects(
 178 |             self.tree.find_all({'a' : True, 'b' : True}),
 179 |             ['First tag.', 'Second tag.', 'Nested tag.'])
 180 | 
 181 |     def test_find_all_by_tag_re(self):
 182 |         self.assert_selects(
 183 |             self.tree.find_all(re.compile('^[ab]$')),
 184 |             ['First tag.', 'Second tag.', 'Nested tag.'])
 185 | 
 186 |     def test_find_all_with_tags_matching_method(self):
 187 |         # You can define an oracle method that determines whether
 188 |         # a tag matches the search.
 189 |         def id_matches_name(tag):
 190 |             return tag.name == tag.get('id')
 191 | 
 192 |         tree = self.soup("""<a id="a">Match 1.</a>
 193 |                             <a id="1">Does not match.</a>
 194 |                             <b id="b">Match 2.</a>""")
 195 | 
 196 |         self.assert_selects(
 197 |             tree.find_all(id_matches_name), ["Match 1.", "Match 2."])
 198 | 
 199 |     def test_find_with_multi_valued_attribute(self):
 200 |         soup = self.soup(
 201 |             "<div class='a b'>1</div><div class='a c'>2</div><div class='a d'>3</div>"
 202 |         )
 203 |         r1 = soup.find('div', 'a d');
 204 |         r2 = soup.find('div', re.compile(r'a d'));
 205 |         r3, r4 = soup.find_all('div', ['a b', 'a d']);
 206 |         assert '3' == r1.string
 207 |         assert '3' == r2.string
 208 |         assert '1' == r3.string
 209 |         assert '3' == r4.string
 210 | 
 211 |         
 212 | class TestFindAllByAttribute(SoupTest):
 213 | 
 214 |     def test_find_all_by_attribute_name(self):
 215 |         # You can pass in keyword arguments to find_all to search by
 216 |         # attribute.
 217 |         tree = self.soup("""
 218 |                          <a id="first">Matching a.</a>
 219 |                          <a id="second">
 220 |                           Non-matching <b id="first">Matching b.</b>a.
 221 |                          </a>""")
 222 |         self.assert_selects(tree.find_all(id='first'),
 223 |                            ["Matching a.", "Matching b."])
 224 | 
 225 |     def test_find_all_by_utf8_attribute_value(self):
 226 |         peace = "םולש".encode("utf8")
 227 |         data = '<a title="םולש"></a>'.encode("utf8")
 228 |         soup = self.soup(data)
 229 |         assert [soup.a] == soup.find_all(title=peace)
 230 |         assert [soup.a] == soup.find_all(title=peace.decode("utf8"))
 231 |         assert [soup.a], soup.find_all(title=[peace, "something else"])
 232 | 
 233 |     def test_find_all_by_attribute_dict(self):
 234 |         # You can pass in a dictionary as the argument 'attrs'. This
 235 |         # lets you search for attributes like 'name' (a fixed argument
 236 |         # to find_all) and 'class' (a reserved word in Python.)
 237 |         tree = self.soup("""
 238 |                          <a name="name1" class="class1">Name match.</a>
 239 |                          <a name="name2" class="class2">Class match.</a>
 240 |                          <a name="name3" class="class3">Non-match.</a>
 241 |                          <name1>A tag called 'name1'.</name1>
 242 |                          """)
 243 | 
 244 |         # This doesn't do what you want.
 245 |         self.assert_selects(tree.find_all(name='name1'),
 246 |                            ["A tag called 'name1'."])
 247 |         # This does what you want.
 248 |         self.assert_selects(tree.find_all(attrs={'name' : 'name1'}),
 249 |                            ["Name match."])
 250 | 
 251 |         self.assert_selects(tree.find_all(attrs={'class' : 'class2'}),
 252 |                            ["Class match."])
 253 | 
 254 |     def test_find_all_by_class(self):
 255 |         tree = self.soup("""
 256 |                          <a class="1">Class 1.</a>
 257 |                          <a class="2">Class 2.</a>
 258 |                          <b class="1">Class 1.</b>
 259 |                          <c class="3 4">Class 3 and 4.</c>
 260 |                          """)
 261 | 
 262 |         # Passing in the class_ keyword argument will search against
 263 |         # the 'class' attribute.
 264 |         self.assert_selects(tree.find_all('a', class_='1'), ['Class 1.'])
 265 |         self.assert_selects(tree.find_all('c', class_='3'), ['Class 3 and 4.'])
 266 |         self.assert_selects(tree.find_all('c', class_='4'), ['Class 3 and 4.'])
 267 | 
 268 |         # Passing in a string to 'attrs' will also search the CSS class.
 269 |         self.assert_selects(tree.find_all('a', '1'), ['Class 1.'])
 270 |         self.assert_selects(tree.find_all(attrs='1'), ['Class 1.', 'Class 1.'])
 271 |         self.assert_selects(tree.find_all('c', '3'), ['Class 3 and 4.'])
 272 |         self.assert_selects(tree.find_all('c', '4'), ['Class 3 and 4.'])
 273 | 
 274 |     def test_find_by_class_when_multiple_classes_present(self):
 275 |         tree = self.soup("<gar class='foo bar'>Found it</gar>")
 276 | 
 277 |         f = tree.find_all("gar", class_=re.compile("o"))
 278 |         self.assert_selects(f, ["Found it"])
 279 | 
 280 |         f = tree.find_all("gar", class_=re.compile("a"))
 281 |         self.assert_selects(f, ["Found it"])
 282 | 
 283 |         # If the search fails to match the individual strings "foo" and "bar",
 284 |         # it will be tried against the combined string "foo bar".
 285 |         f = tree.find_all("gar", class_=re.compile("o b"))
 286 |         self.assert_selects(f, ["Found it"])
 287 | 
 288 |     def test_find_all_with_non_dictionary_for_attrs_finds_by_class(self):
 289 |         soup = self.soup("<a class='bar'>Found it</a>")
 290 | 
 291 |         self.assert_selects(soup.find_all("a", re.compile("ba")), ["Found it"])
 292 | 
 293 |         def big_attribute_value(value):
 294 |             return len(value) > 3
 295 | 
 296 |         self.assert_selects(soup.find_all("a", big_attribute_value), [])
 297 | 
 298 |         def small_attribute_value(value):
 299 |             return len(value) <= 3
 300 | 
 301 |         self.assert_selects(
 302 |             soup.find_all("a", small_attribute_value), ["Found it"])
 303 | 
 304 |     def test_find_all_with_string_for_attrs_finds_multiple_classes(self):
 305 |         soup = self.soup('<a class="foo bar"></a><a class="foo"></a>')
 306 |         a, a2 = soup.find_all("a")
 307 |         assert [a, a2], soup.find_all("a", "foo")
 308 |         assert [a], soup.find_all("a", "bar")
 309 | 
 310 |         # If you specify the class as a string that contains a
 311 |         # space, only that specific value will be found.
 312 |         assert [a] == soup.find_all("a", class_="foo bar")
 313 |         assert [a] == soup.find_all("a", "foo bar")
 314 |         assert [] == soup.find_all("a", "bar foo")
 315 | 
 316 |     def test_find_all_by_attribute_soupstrainer(self):
 317 |         tree = self.soup("""
 318 |                          <a id="first">Match.</a>
 319 |                          <a id="second">Non-match.</a>""")
 320 | 
 321 |         strainer = SoupStrainer(attrs={'id' : 'first'})
 322 |         self.assert_selects(tree.find_all(strainer), ['Match.'])
 323 | 
 324 |     def test_find_all_with_missing_attribute(self):
 325 |         # You can pass in None as the value of an attribute to find_all.
 326 |         # This will match tags that do not have that attribute set.
 327 |         tree = self.soup("""<a id="1">ID present.</a>
 328 |                             <a>No ID present.</a>
 329 |                             <a id="">ID is empty.</a>""")
 330 |         self.assert_selects(tree.find_all('a', id=None), ["No ID present."])
 331 | 
 332 |     def test_find_all_with_defined_attribute(self):
 333 |         # You can pass in None as the value of an attribute to find_all.
 334 |         # This will match tags that have that attribute set to any value.
 335 |         tree = self.soup("""<a id="1">ID present.</a>
 336 |                             <a>No ID present.</a>
 337 |                             <a id="">ID is empty.</a>""")
 338 |         self.assert_selects(
 339 |             tree.find_all(id=True), ["ID present.", "ID is empty."])
 340 | 
 341 |     def test_find_all_with_numeric_attribute(self):
 342 |         # If you search for a number, it's treated as a string.
 343 |         tree = self.soup("""<a id=1>Unquoted attribute.</a>
 344 |                             <a id="1">Quoted attribute.</a>""")
 345 | 
 346 |         expected = ["Unquoted attribute.", "Quoted attribute."]
 347 |         self.assert_selects(tree.find_all(id=1), expected)
 348 |         self.assert_selects(tree.find_all(id="1"), expected)
 349 | 
 350 |     def test_find_all_with_list_attribute_values(self):
 351 |         # You can pass a list of attribute values instead of just one,
 352 |         # and you'll get tags that match any of the values.
 353 |         tree = self.soup("""<a id="1">1</a>
 354 |                             <a id="2">2</a>
 355 |                             <a id="3">3</a>
 356 |                             <a>No ID.</a>""")
 357 |         self.assert_selects(tree.find_all(id=["1", "3", "4"]),
 358 |                            ["1", "3"])
 359 | 
 360 |     def test_find_all_with_regular_expression_attribute_value(self):
 361 |         # You can pass a regular expression as an attribute value, and
 362 |         # you'll get tags whose values for that attribute match the
 363 |         # regular expression.
 364 |         tree = self.soup("""<a id="a">One a.</a>
 365 |                             <a id="aa">Two as.</a>
 366 |                             <a id="ab">Mixed as and bs.</a>
 367 |                             <a id="b">One b.</a>
 368 |                             <a>No ID.</a>""")
 369 | 
 370 |         self.assert_selects(tree.find_all(id=re.compile("^a+$")),
 371 |                            ["One a.", "Two as."])
 372 | 
 373 |     def test_find_by_name_and_containing_string(self):
 374 |         soup = self.soup("<b>foo</b><b>bar</b><a>foo</a>")
 375 |         a = soup.a
 376 | 
 377 |         assert [a] == soup.find_all("a", string="foo")
 378 |         assert [] == soup.find_all("a", string="bar")
 379 | 
 380 |     def test_find_by_name_and_containing_string_when_string_is_buried(self):
 381 |         soup = self.soup("<a>foo</a><a><b><c>foo</c></b></a>")
 382 |         assert soup.find_all("a") == soup.find_all("a", string="foo")
 383 | 
 384 |     def test_find_by_attribute_and_containing_string(self):
 385 |         soup = self.soup('<b id="1">foo</b><a id="2">foo</a>')
 386 |         a = soup.a
 387 | 
 388 |         assert [a] == soup.find_all(id=2, string="foo")
 389 |         assert [] == soup.find_all(id=1, string="bar")
 390 | 
 391 | 
 392 | class TestSmooth(SoupTest):
 393 |     """Test Tag.smooth."""
 394 | 
 395 |     def test_smooth(self):
 396 |         soup = self.soup("<div>a</div>")
 397 |         div = soup.div
 398 |         div.append("b")
 399 |         div.append("c")
 400 |         div.append(Comment("Comment 1"))
 401 |         div.append(Comment("Comment 2"))
 402 |         div.append("d")
 403 |         builder = self.default_builder()
 404 |         span = Tag(soup, builder, 'span')
 405 |         span.append('1')
 406 |         span.append('2')
 407 |         div.append(span)
 408 | 
 409 |         # At this point the tree has a bunch of adjacent
 410 |         # NavigableStrings. This is normal, but it has no meaning in
 411 |         # terms of HTML, so we may want to smooth things out for
 412 |         # output.
 413 | 
 414 |         # Since the <span> tag has two children, its .string is None.
 415 |         assert None == div.span.string
 416 | 
 417 |         assert 7 == len(div.contents)
 418 |         div.smooth()
 419 |         assert 5 == len(div.contents)
 420 | 
 421 |         # The three strings at the beginning of div.contents have been
 422 |         # merged into on string.
 423 |         #
 424 |         assert 'abc' == div.contents[0]
 425 | 
 426 |         # The call is recursive -- the <span> tag was also smoothed.
 427 |         assert '12' == div.span.string
 428 | 
 429 |         # The two comments have _not_ been merged, even though
 430 |         # comments are strings. Merging comments would change the
 431 |         # meaning of the HTML.
 432 |         assert 'Comment 1' == div.contents[1]
 433 |         assert 'Comment 2' == div.contents[2]
 434 | 
 435 | 
 436 | class TestIndex(SoupTest):
 437 |     """Test Tag.index"""
 438 |     def test_index(self):
 439 |         tree = self.soup("""<div>
 440 |                             <a>Identical</a>
 441 |                             <b>Not identical</b>
 442 |                             <a>Identical</a>
 443 | 
 444 |                             <c><d>Identical with child</d></c>
 445 |                             <b>Also not identical</b>
 446 |                             <c><d>Identical with child</d></c>
 447 |                             </div>""")
 448 |         div = tree.div
 449 |         for i, element in enumerate(div.contents):
 450 |             assert i == div.index(element)
 451 |         with pytest.raises(ValueError):
 452 |             tree.index(1)
 453 | 
 454 | 
 455 | class TestParentOperations(SoupTest):
 456 |     """Test navigation and searching through an element's parents."""
 457 | 
 458 |     def setup_method(self):
 459 |         self.tree = self.soup('''<ul id="empty"></ul>
 460 |                                  <ul id="top">
 461 |                                   <ul id="middle">
 462 |                                    <ul id="bottom">
 463 |                                     <b>Start here</b>
 464 |                                    </ul>
 465 |                                   </ul>''')
 466 |         self.start = self.tree.b
 467 | 
 468 | 
 469 |     def test_parent(self):
 470 |         assert self.start.parent['id'] == 'bottom'
 471 |         assert self.start.parent.parent['id'] == 'middle'
 472 |         assert self.start.parent.parent.parent['id'] == 'top'
 473 | 
 474 |     def test_parent_of_top_tag_is_soup_object(self):
 475 |         top_tag = self.tree.contents[0]
 476 |         assert top_tag.parent == self.tree
 477 | 
 478 |     def test_soup_object_has_no_parent(self):
 479 |         assert None == self.tree.parent
 480 | 
 481 |     def test_find_parents(self):
 482 |         self.assert_selects_ids(
 483 |             self.start.find_parents('ul'), ['bottom', 'middle', 'top'])
 484 |         self.assert_selects_ids(
 485 |             self.start.find_parents('ul', id="middle"), ['middle'])
 486 | 
 487 |     def test_find_parent(self):
 488 |         assert self.start.find_parent('ul')['id'] == 'bottom'
 489 |         assert self.start.find_parent('ul', id='top')['id'] == 'top'
 490 | 
 491 |     def test_parent_of_text_element(self):
 492 |         text = self.tree.find(string="Start here")
 493 |         assert text.parent.name == 'b'
 494 | 
 495 |     def test_text_element_find_parent(self):
 496 |         text = self.tree.find(string="Start here")
 497 |         assert text.find_parent('ul')['id'] == 'bottom'
 498 | 
 499 |     def test_parent_generator(self):
 500 |         parents = [parent['id'] for parent in self.start.parents
 501 |                    if parent is not None and 'id' in parent.attrs]
 502 |         assert parents, ['bottom', 'middle' == 'top']
 503 | 
 504 | 
 505 | class ProximityTest(SoupTest):
 506 | 
 507 |     def setup_method(self):
 508 |         self.tree = self.soup(
 509 |             '<html id="start"><head></head><body><b id="1">One</b><b id="2">Two</b><b id="3">Three</b></body></html>')
 510 | 
 511 | 
 512 | class TestNextOperations(ProximityTest):
 513 | 
 514 |     def setup_method(self):
 515 |         super(TestNextOperations, self).setup_method()
 516 |         self.start = self.tree.b
 517 | 
 518 |     def test_next(self):
 519 |         assert self.start.next_element == "One"
 520 |         assert self.start.next_element.next_element['id'] == "2"
 521 | 
 522 |     def test_next_of_last_item_is_none(self):
 523 |         last = self.tree.find(string="Three")
 524 |         assert last.next_element == None
 525 | 
 526 |     def test_next_of_root_is_none(self):
 527 |         # The document root is outside the next/previous chain.
 528 |         assert self.tree.next_element == None
 529 | 
 530 |     def test_find_all_next(self):
 531 |         self.assert_selects(self.start.find_all_next('b'), ["Two", "Three"])
 532 |         self.start.find_all_next(id=3)
 533 |         self.assert_selects(self.start.find_all_next(id=3), ["Three"])
 534 | 
 535 |     def test_find_next(self):
 536 |         assert self.start.find_next('b')['id'] == '2'
 537 |         assert self.start.find_next(string="Three") == "Three"
 538 | 
 539 |     def test_find_next_for_text_element(self):
 540 |         text = self.tree.find(string="One")
 541 |         assert text.find_next("b").string == "Two"
 542 |         self.assert_selects(text.find_all_next("b"), ["Two", "Three"])
 543 | 
 544 |     def test_next_generator(self):
 545 |         start = self.tree.find(string="Two")
 546 |         successors = [node for node in start.next_elements]
 547 |         # There are two successors: the final <b> tag and its text contents.
 548 |         tag, contents = successors
 549 |         assert tag['id'] == '3'
 550 |         assert contents == "Three"
 551 | 
 552 | class TestPreviousOperations(ProximityTest):
 553 | 
 554 |     def setup_method(self):
 555 |         super(TestPreviousOperations, self).setup_method()
 556 |         self.end = self.tree.find(string="Three")
 557 | 
 558 |     def test_previous(self):
 559 |         assert self.end.previous_element['id'] == "3"
 560 |         assert self.end.previous_element.previous_element == "Two"
 561 | 
 562 |     def test_previous_of_first_item_is_none(self):
 563 |         first = self.tree.find('html')
 564 |         assert first.previous_element == None
 565 | 
 566 |     def test_previous_of_root_is_none(self):
 567 |         # The document root is outside the next/previous chain.
 568 |         assert self.tree.previous_element == None
 569 | 
 570 |     def test_find_all_previous(self):
 571 |         # The <b> tag containing the "Three" node is the predecessor
 572 |         # of the "Three" node itself, which is why "Three" shows up
 573 |         # here.
 574 |         self.assert_selects(
 575 |             self.end.find_all_previous('b'), ["Three", "Two", "One"])
 576 |         self.assert_selects(self.end.find_all_previous(id=1), ["One"])
 577 | 
 578 |     def test_find_previous(self):
 579 |         assert self.end.find_previous('b')['id'] == '3'
 580 |         assert self.end.find_previous(string="One") == "One"
 581 | 
 582 |     def test_find_previous_for_text_element(self):
 583 |         text = self.tree.find(string="Three")
 584 |         assert text.find_previous("b").string == "Three"
 585 |         self.assert_selects(
 586 |             text.find_all_previous("b"), ["Three", "Two", "One"])
 587 | 
 588 |     def test_previous_generator(self):
 589 |         start = self.tree.find(string="One")
 590 |         predecessors = [node for node in start.previous_elements]
 591 | 
 592 |         # There are four predecessors: the <b> tag containing "One"
 593 |         # the <body> tag, the <head> tag, and the <html> tag.
 594 |         b, body, head, html = predecessors
 595 |         assert b['id'] == '1'
 596 |         assert body.name == "body"
 597 |         assert head.name == "head"
 598 |         assert html.name == "html"
 599 | 
 600 | 
 601 | class SiblingTest(SoupTest):
 602 | 
 603 |     def setup_method(self):
 604 |         markup = '''<html>
 605 |                     <span id="1">
 606 |                      <span id="1.1"></span>
 607 |                     </span>
 608 |                     <span id="2">
 609 |                      <span id="2.1"></span>
 610 |                     </span>
 611 |                     <span id="3">
 612 |                      <span id="3.1"></span>
 613 |                     </span>
 614 |                     <span id="4"></span>
 615 |                     </html>'''
 616 |         # All that whitespace looks good but makes the tests more
 617 |         # difficult. Get rid of it.
 618 |         markup = re.compile(r"\n\s*").sub("", markup)
 619 |         self.tree = self.soup(markup)
 620 | 
 621 | 
 622 | class TestNextSibling(SiblingTest):
 623 | 
 624 |     def setup_method(self):
 625 |         super(TestNextSibling, self).setup_method()
 626 |         self.start = self.tree.find(id="1")
 627 | 
 628 |     def test_next_sibling_of_root_is_none(self):
 629 |         assert self.tree.next_sibling == None
 630 | 
 631 |     def test_next_sibling(self):
 632 |         assert self.start.next_sibling['id'] == '2'
 633 |         assert self.start.next_sibling.next_sibling['id'] == '3'
 634 | 
 635 |         # Note the difference between next_sibling and next_element.
 636 |         assert self.start.next_element['id'] == '1.1'
 637 | 
 638 |     def test_next_sibling_may_not_exist(self):
 639 |         assert self.tree.html.next_sibling == None
 640 | 
 641 |         nested_span = self.tree.find(id="1.1")
 642 |         assert nested_span.next_sibling == None
 643 | 
 644 |         last_span = self.tree.find(id="4")
 645 |         assert last_span.next_sibling == None
 646 | 
 647 |     def test_find_next_sibling(self):
 648 |         assert self.start.find_next_sibling('span')['id'] == '2'
 649 | 
 650 |     def test_next_siblings(self):
 651 |         self.assert_selects_ids(self.start.find_next_siblings("span"),
 652 |                               ['2', '3', '4'])
 653 | 
 654 |         self.assert_selects_ids(self.start.find_next_siblings(id='3'), ['3'])
 655 | 
 656 |     def test_next_sibling_for_text_element(self):
 657 |         soup = self.soup("Foo<b>bar</b>baz")
 658 |         start = soup.find(string="Foo")
 659 |         assert start.next_sibling.name == 'b'
 660 |         assert start.next_sibling.next_sibling == 'baz'
 661 | 
 662 |         self.assert_selects(start.find_next_siblings('b'), ['bar'])
 663 |         assert start.find_next_sibling(string="baz") == "baz"
 664 |         assert start.find_next_sibling(string="nonesuch") == None
 665 | 
 666 | 
 667 | class TestPreviousSibling(SiblingTest):
 668 | 
 669 |     def setup_method(self):
 670 |         super(TestPreviousSibling, self).setup_method()
 671 |         self.end = self.tree.find(id="4")
 672 | 
 673 |     def test_previous_sibling_of_root_is_none(self):
 674 |         assert self.tree.previous_sibling == None
 675 | 
 676 |     def test_previous_sibling(self):
 677 |         assert self.end.previous_sibling['id'] == '3'
 678 |         assert self.end.previous_sibling.previous_sibling['id'] == '2'
 679 | 
 680 |         # Note the difference between previous_sibling and previous_element.
 681 |         assert self.end.previous_element['id'] == '3.1'
 682 | 
 683 |     def test_previous_sibling_may_not_exist(self):
 684 |         assert self.tree.html.previous_sibling == None
 685 | 
 686 |         nested_span = self.tree.find(id="1.1")
 687 |         assert nested_span.previous_sibling == None
 688 | 
 689 |         first_span = self.tree.find(id="1")
 690 |         assert first_span.previous_sibling == None
 691 | 
 692 |     def test_find_previous_sibling(self):
 693 |         assert self.end.find_previous_sibling('span')['id'] == '3'
 694 | 
 695 |     def test_previous_siblings(self):
 696 |         self.assert_selects_ids(self.end.find_previous_siblings("span"),
 697 |                               ['3', '2', '1'])
 698 | 
 699 |         self.assert_selects_ids(self.end.find_previous_siblings(id='1'), ['1'])
 700 | 
 701 |     def test_previous_sibling_for_text_element(self):
 702 |         soup = self.soup("Foo<b>bar</b>baz")
 703 |         start = soup.find(string="baz")
 704 |         assert start.previous_sibling.name == 'b'
 705 |         assert start.previous_sibling.previous_sibling == 'Foo'
 706 | 
 707 |         self.assert_selects(start.find_previous_siblings('b'), ['bar'])
 708 |         assert start.find_previous_sibling(string="Foo") == "Foo"
 709 |         assert start.find_previous_sibling(string="nonesuch") == None
 710 | 
 711 | 
 712 | class TestTreeModification(SoupTest):
 713 | 
 714 |     def test_attribute_modification(self):
 715 |         soup = self.soup('<a id="1"></a>')
 716 |         soup.a['id'] = 2
 717 |         assert soup.decode() == self.document_for('<a id="2"></a>')
 718 |         del(soup.a['id'])
 719 |         assert soup.decode() == self.document_for('<a></a>')
 720 |         soup.a['id2'] = 'foo'
 721 |         assert soup.decode() == self.document_for('<a id2="foo"></a>')
 722 | 
 723 |     def test_new_tag_creation(self):
 724 |         builder = builder_registry.lookup('html')()
 725 |         soup = self.soup("<body></body>", builder=builder)
 726 |         a = Tag(soup, builder, 'a')
 727 |         ol = Tag(soup, builder, 'ol')
 728 |         a['href'] = 'http://foo.com/'
 729 |         soup.body.insert(0, a)
 730 |         soup.body.insert(1, ol)
 731 |         assert soup.body.encode() == b'<body><a href="http://foo.com/"></a><ol></ol></body>'
 732 | 
 733 |     def test_append_to_contents_moves_tag(self):
 734 |         doc = """<p id="1">Don't leave me <b>here</b>.</p>
 735 |                 <p id="2">Don\'t leave!</p>"""
 736 |         soup = self.soup(doc)
 737 |         second_para = soup.find(id='2')
 738 |         bold = soup.b
 739 | 
 740 |         # Move the <b> tag to the end of the second paragraph.
 741 |         soup.find(id='2').append(soup.b)
 742 | 
 743 |         # The <b> tag is now a child of the second paragraph.
 744 |         assert bold.parent == second_para
 745 | 
 746 |         assert soup.decode() == self.document_for(
 747 |                 '<p id="1">Don\'t leave me .</p>\n'
 748 |                 '<p id="2">Don\'t leave!<b>here</b></p>'
 749 |         )
 750 | 
 751 |     def test_replace_with_returns_thing_that_was_replaced(self):
 752 |         text = "<a></a><b><c></c></b>"
 753 |         soup = self.soup(text)
 754 |         a = soup.a
 755 |         new_a = a.replace_with(soup.c)
 756 |         assert a == new_a
 757 | 
 758 |     def test_unwrap_returns_thing_that_was_replaced(self):
 759 |         text = "<a><b></b><c></c></a>"
 760 |         soup = self.soup(text)
 761 |         a = soup.a
 762 |         new_a = a.unwrap()
 763 |         assert a == new_a
 764 | 
 765 |     def test_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parent(self):
 766 |         soup = self.soup("<a><b>Foo</b></a><c>Bar</c>")
 767 |         a = soup.a
 768 |         a.extract()
 769 |         assert None == a.parent
 770 |         with pytest.raises(ValueError):
 771 |             a.unwrap()
 772 |         with pytest.raises(ValueError):
 773 |             a.replace_with(soup.c)
 774 | 
 775 |     def test_replace_tag_with_itself(self):
 776 |         text = "<a><b></b><c>Foo<d></d></c></a><a><e></e></a>"
 777 |         soup = self.soup(text)
 778 |         c = soup.c
 779 |         soup.c.replace_with(c)
 780 |         assert soup.decode() == self.document_for(text)
 781 | 
 782 |     def test_replace_tag_with_its_parent_raises_exception(self):
 783 |         text = "<a><b></b></a>"
 784 |         soup = self.soup(text)
 785 |         with pytest.raises(ValueError):
 786 |             soup.b.replace_with(soup.a)
 787 | 
 788 |     def test_insert_tag_into_itself_raises_exception(self):
 789 |         text = "<a><b></b></a>"
 790 |         soup = self.soup(text)
 791 |         with pytest.raises(ValueError):
 792 |             soup.a.insert(0, soup.a)
 793 | 
 794 |     def test_insert_beautifulsoup_object_inserts_children(self):
 795 |         """Inserting one BeautifulSoup object into another actually inserts all
 796 |         of its children -- you'll never combine BeautifulSoup objects.
 797 |         """
 798 |         soup = self.soup("<p>And now, a word:</p><p>And we're back.</p>")
 799 |         
 800 |         text = "<p>p2</p><p>p3</p>"
 801 |         to_insert = self.soup(text)
 802 |         soup.insert(1, to_insert)
 803 | 
 804 |         for i in soup.descendants:
 805 |             assert not isinstance(i, BeautifulSoup)
 806 |         
 807 |         p1, p2, p3, p4 = list(soup.children)
 808 |         assert "And now, a word:" == p1.string
 809 |         assert "p2" == p2.string
 810 |         assert "p3" == p3.string
 811 |         assert "And we're back." == p4.string
 812 |         
 813 |         
 814 |     def test_replace_with_maintains_next_element_throughout(self):
 815 |         soup = self.soup('<p><a>one</a><b>three</b></p>')
 816 |         a = soup.a
 817 |         b = a.contents[0]
 818 |         # Make it so the <a> tag has two text children.
 819 |         a.insert(1, "two")
 820 | 
 821 |         # Now replace each one with the empty string.
 822 |         left, right = a.contents
 823 |         left.replaceWith('')
 824 |         right.replaceWith('')
 825 | 
 826 |         # The <b> tag is still connected to the tree.
 827 |         assert "three" == soup.b.string
 828 | 
 829 |     def test_replace_final_node(self):
 830 |         soup = self.soup("<b>Argh!</b>")
 831 |         soup.find(string="Argh!").replace_with("Hooray!")
 832 |         new_text = soup.find(string="Hooray!")
 833 |         b = soup.b
 834 |         assert new_text.previous_element == b
 835 |         assert new_text.parent == b
 836 |         assert new_text.previous_element.next_element == new_text
 837 |         assert new_text.next_element == None
 838 | 
 839 |     def test_consecutive_text_nodes(self):
 840 |         # A builder should never create two consecutive text nodes,
 841 |         # but if you insert one next to another, Beautiful Soup will
 842 |         # handle it correctly.
 843 |         soup = self.soup("<a><b>Argh!</b><c></c></a>")
 844 |         soup.b.insert(1, "Hooray!")
 845 | 
 846 |         assert soup.decode() == self.document_for(
 847 |             "<a><b>Argh!Hooray!</b><c></c></a>"
 848 |         )
 849 | 
 850 |         new_text = soup.find(string="Hooray!")
 851 |         assert new_text.previous_element == "Argh!"
 852 |         assert new_text.previous_element.next_element == new_text
 853 | 
 854 |         assert new_text.previous_sibling == "Argh!"
 855 |         assert new_text.previous_sibling.next_sibling == new_text
 856 | 
 857 |         assert new_text.next_sibling == None
 858 |         assert new_text.next_element == soup.c
 859 | 
 860 |     def test_insert_string(self):
 861 |         soup = self.soup("<a></a>")
 862 |         soup.a.insert(0, "bar")
 863 |         soup.a.insert(0, "foo")
 864 |         # The string were added to the tag.
 865 |         assert ["foo", "bar"] == soup.a.contents
 866 |         # And they were converted to NavigableStrings.
 867 |         assert soup.a.contents[0].next_element == "bar"
 868 | 
 869 |     def test_insert_tag(self):
 870 |         builder = self.default_builder()
 871 |         soup = self.soup(
 872 |             "<a><b>Find</b><c>lady!</c><d></d></a>", builder=builder)
 873 |         magic_tag = Tag(soup, builder, 'magictag')
 874 |         magic_tag.insert(0, "the")
 875 |         soup.a.insert(1, magic_tag)
 876 | 
 877 |         assert soup.decode() == self.document_for(
 878 |                 "<a><b>Find</b><magictag>the</magictag><c>lady!</c><d></d></a>"
 879 |         )
 880 | 
 881 |         # Make sure all the relationships are hooked up correctly.
 882 |         b_tag = soup.b
 883 |         assert b_tag.next_sibling == magic_tag
 884 |         assert magic_tag.previous_sibling == b_tag
 885 | 
 886 |         find = b_tag.find(string="Find")
 887 |         assert find.next_element == magic_tag
 888 |         assert magic_tag.previous_element == find
 889 | 
 890 |         c_tag = soup.c
 891 |         assert magic_tag.next_sibling == c_tag
 892 |         assert c_tag.previous_sibling == magic_tag
 893 | 
 894 |         the = magic_tag.find(string="the")
 895 |         assert the.parent == magic_tag
 896 |         assert the.next_element == c_tag
 897 |         assert c_tag.previous_element == the
 898 | 
 899 |     def test_append_child_thats_already_at_the_end(self):
 900 |         data = "<a><b></b></a>"
 901 |         soup = self.soup(data)
 902 |         soup.a.append(soup.b)
 903 |         assert data == soup.decode()
 904 | 
 905 |     def test_extend(self):
 906 |         data = "<a><b><c><d><e><f><g></g></f></e></d></c></b></a>"
 907 |         soup = self.soup(data)
 908 |         l = [soup.g, soup.f, soup.e, soup.d, soup.c, soup.b]
 909 |         soup.a.extend(l)
 910 |         assert "<a><g></g><f></f><e></e><d></d><c></c><b></b></a>" == soup.decode()
 911 | 
 912 |     @pytest.mark.parametrize(
 913 |         "get_tags", [lambda tag: tag, lambda tag: tag.contents]
 914 |     )
 915 |     def test_extend_with_another_tags_contents(self, get_tags):
 916 |         data = '<body><div id="d1"><a>1</a><a>2</a><a>3</a><a>4</a></div><div id="d2"></div></body>'
 917 |         soup = self.soup(data)
 918 |         d1 = soup.find('div', id='d1')
 919 |         d2 = soup.find('div', id='d2')
 920 |         tags = get_tags(d1)
 921 |         d2.extend(tags)
 922 |         assert '<div id="d1"></div>' == d1.decode()
 923 |         assert '<div id="d2"><a>1</a><a>2</a><a>3</a><a>4</a></div>' == d2.decode()
 924 |         
 925 |     def test_move_tag_to_beginning_of_parent(self):
 926 |         data = "<a><b></b><c></c><d></d></a>"
 927 |         soup = self.soup(data)
 928 |         soup.a.insert(0, soup.d)
 929 |         assert "<a><d></d><b></b><c></c></a>" == soup.decode()
 930 | 
 931 |     def test_insert_works_on_empty_element_tag(self):
 932 |         # This is a little strange, since most HTML parsers don't allow
 933 |         # markup like this to come through. But in general, we don't
 934 |         # know what the parser would or wouldn't have allowed, so
 935 |         # I'm letting this succeed for now.
 936 |         soup = self.soup("<br/>")
 937 |         soup.br.insert(1, "Contents")
 938 |         assert str(soup.br) == "<br>Contents</br>"
 939 | 
 940 |     def test_insert_before(self):
 941 |         soup = self.soup("<a>foo</a><b>bar</b>")
 942 |         soup.b.insert_before("BAZ")
 943 |         soup.a.insert_before("QUUX")
 944 |         assert soup.decode() == self.document_for(
 945 |             "QUUX<a>foo</a>BAZ<b>bar</b>"
 946 |         )
 947 | 
 948 |         soup.a.insert_before(soup.b)
 949 |         assert soup.decode() == self.document_for("QUUX<b>bar</b><a>foo</a>BAZ")
 950 | 
 951 |         # Can't insert an element before itself.
 952 |         b = soup.b
 953 |         with pytest.raises(ValueError):
 954 |             b.insert_before(b)
 955 | 
 956 |         # Can't insert before if an element has no parent.
 957 |         b.extract()
 958 |         with pytest.raises(ValueError):
 959 |             b.insert_before("nope")
 960 | 
 961 |         # Can insert an identical element
 962 |         soup = self.soup("<a>")
 963 |         soup.a.insert_before(soup.new_tag("a"))
 964 | 
 965 |         # TODO: OK but what happens?
 966 |         
 967 |     def test_insert_multiple_before(self):
 968 |         soup = self.soup("<a>foo</a><b>bar</b>")
 969 |         soup.b.insert_before("BAZ", " ", "QUUX")
 970 |         soup.a.insert_before("QUUX", " ", "BAZ")
 971 |         assert soup.decode() == self.document_for(
 972 |             "QUUX BAZ<a>foo</a>BAZ QUUX<b>bar</b>"
 973 |         )
 974 | 
 975 |         soup.a.insert_before(soup.b, "FOO")
 976 |         assert soup.decode() == self.document_for(
 977 |             "QUUX BAZ<b>bar</b>FOO<a>foo</a>BAZ QUUX"
 978 |         )
 979 | 
 980 |     def test_insert_after(self):
 981 |         soup = self.soup("<a>foo</a><b>bar</b>")
 982 |         soup.b.insert_after("BAZ")
 983 |         soup.a.insert_after("QUUX")
 984 |         assert soup.decode() == self.document_for(
 985 |             "<a>foo</a>QUUX<b>bar</b>BAZ"
 986 |         )
 987 |         soup.b.insert_after(soup.a)
 988 |         assert soup.decode() == self.document_for("QUUX<b>bar</b><a>foo</a>BAZ")
 989 | 
 990 |         # Can't insert an element after itself.
 991 |         b = soup.b
 992 |         with pytest.raises(ValueError):
 993 |             b.insert_after(b)
 994 | 
 995 |         # Can't insert after if an element has no parent.
 996 |         b.extract()
 997 |         with pytest.raises(ValueError):
 998 |             b.insert_after("nope")
 999 | 
1000 |         # Can insert an identical element
1001 |         soup = self.soup("<a>")
1002 |         soup.a.insert_before(soup.new_tag("a"))
1003 | 
1004 |         # TODO: OK but what does it look like?
1005 |         
1006 |     def test_insert_multiple_after(self):
1007 |         soup = self.soup("<a>foo</a><b>bar</b>")
1008 |         soup.b.insert_after("BAZ", " ", "QUUX")
1009 |         soup.a.insert_after("QUUX", " ", "BAZ")
1010 |         assert soup.decode() == self.document_for(
1011 |             "<a>foo</a>QUUX BAZ<b>bar</b>BAZ QUUX"
1012 |         )
1013 |         soup.b.insert_after(soup.a, "FOO ")
1014 |         assert soup.decode() == self.document_for(
1015 |             "QUUX BAZ<b>bar</b><a>foo</a>FOO BAZ QUUX"
1016 |         )
1017 | 
1018 |     def test_insert_after_raises_exception_if_after_has_no_meaning(self):
1019 |         soup = self.soup("")
1020 |         tag = soup.new_tag("a")
1021 |         string = soup.new_string("")
1022 |         with pytest.raises(ValueError):
1023 |             string.insert_after(tag)
1024 |         with pytest.raises(NotImplementedError):
1025 |             soup.insert_after(tag)
1026 |         with pytest.raises(ValueError):
1027 |             tag.insert_after(tag)
1028 | 
1029 |     def test_insert_before_raises_notimplementederror_if_before_has_no_meaning(self):
1030 |         soup = self.soup("")
1031 |         tag = soup.new_tag("a")
1032 |         string = soup.new_string("")
1033 |         with pytest.raises(ValueError):
1034 |             string.insert_before(tag)
1035 |         with pytest.raises(NotImplementedError):
1036 |             soup.insert_before(tag)
1037 |         with pytest.raises(ValueError):
1038 |             tag.insert_before(tag)
1039 | 
1040 |     def test_replace_with(self):
1041 |         soup = self.soup(
1042 |                 "<p>There's <b>no</b> business like <b>show</b> business</p>")
1043 |         no, show = soup.find_all('b')
1044 |         show.replace_with(no)
1045 |         assert soup.decode() == self.document_for(
1046 |             "<p>There's  business like <b>no</b> business</p>"
1047 |         )
1048 | 
1049 |         assert show.parent == None
1050 |         assert no.parent == soup.p
1051 |         assert no.next_element == "no"
1052 |         assert no.next_sibling == " business"
1053 | 
1054 |     def test_replace_with_errors(self):
1055 |         # Can't replace a tag that's not part of a tree.
1056 |         a_tag = Tag(name="a")
1057 |         with pytest.raises(ValueError):
1058 |             a_tag.replace_with("won't work")
1059 | 
1060 |         # Can't replace a tag with its parent.
1061 |         a_tag = self.soup("<a><b></b></a>").a
1062 |         with pytest.raises(ValueError):
1063 |             a_tag.b.replace_with(a_tag)
1064 | 
1065 |         # Or with a list that includes its parent.
1066 |         with pytest.raises(ValueError):
1067 |             a_tag.b.replace_with("string1", a_tag, "string2")
1068 |         
1069 |     def test_replace_with_multiple(self):
1070 |         data = "<a><b></b><c></c></a>"
1071 |         soup = self.soup(data)
1072 |         d_tag = soup.new_tag("d")
1073 |         d_tag.string = "Text In D Tag"
1074 |         e_tag = soup.new_tag("e")
1075 |         f_tag = soup.new_tag("f")
1076 |         a_string = "Random Text"
1077 |         soup.c.replace_with(d_tag, e_tag, a_string, f_tag)
1078 |         assert soup.decode() == "<a><b></b><d>Text In D Tag</d><e></e>Random Text<f></f></a>"
1079 |         assert soup.b.next_element == d_tag
1080 |         assert d_tag.string.next_element==e_tag
1081 |         assert e_tag.next_element.string == a_string
1082 |         assert e_tag.next_element.next_element == f_tag
1083 |         
1084 |     def test_replace_first_child(self):
1085 |         data = "<a><b></b><c></c></a>"
1086 |         soup = self.soup(data)
1087 |         soup.b.replace_with(soup.c)
1088 |         assert "<a><c></c></a>" == soup.decode()
1089 | 
1090 |     def test_replace_last_child(self):
1091 |         data = "<a><b></b><c></c></a>"
1092 |         soup = self.soup(data)
1093 |         soup.c.replace_with(soup.b)
1094 |         assert "<a><b></b></a>" == soup.decode()
1095 | 
1096 |     def test_nested_tag_replace_with(self):
1097 |         soup = self.soup(
1098 |             """<a>We<b>reserve<c>the</c><d>right</d></b></a><e>to<f>refuse</f><g>service</g></e>""")
1099 | 
1100 |         # Replace the entire <b> tag and its contents ("reserve the
1101 |         # right") with the <f> tag ("refuse").
1102 |         remove_tag = soup.b
1103 |         move_tag = soup.f
1104 |         remove_tag.replace_with(move_tag)
1105 | 
1106 |         assert soup.decode() == self.document_for(
1107 |             "<a>We<f>refuse</f></a><e>to<g>service</g></e>"
1108 |         )
1109 | 
1110 |         # The <b> tag is now an orphan.
1111 |         assert remove_tag.parent == None
1112 |         assert remove_tag.find(string="right").next_element == None
1113 |         assert remove_tag.previous_element == None
1114 |         assert remove_tag.next_sibling == None
1115 |         assert remove_tag.previous_sibling == None
1116 | 
1117 |         # The <f> tag is now connected to the <a> tag.
1118 |         assert move_tag.parent == soup.a
1119 |         assert move_tag.previous_element == "We"
1120 |         assert move_tag.next_element.next_element == soup.e
1121 |         assert move_tag.next_sibling == None
1122 | 
1123 |         # The gap where the <f> tag used to be has been mended, and
1124 |         # the word "to" is now connected to the <g> tag.
1125 |         to_text = soup.find(string="to")
1126 |         g_tag = soup.g
1127 |         assert to_text.next_element == g_tag
1128 |         assert to_text.next_sibling == g_tag
1129 |         assert g_tag.previous_element == to_text
1130 |         assert g_tag.previous_sibling == to_text
1131 | 
1132 |     def test_unwrap(self):
1133 |         tree = self.soup("""
1134 |             <p>Unneeded <em>formatting</em> is unneeded</p>
1135 |             """)
1136 |         tree.em.unwrap()
1137 |         assert tree.em == None
1138 |         assert tree.p.text == "Unneeded formatting is unneeded"
1139 | 
1140 |     def test_wrap(self):
1141 |         soup = self.soup("I wish I was bold.")
1142 |         value = soup.string.wrap(soup.new_tag("b"))
1143 |         assert value.decode() == "<b>I wish I was bold.</b>"
1144 |         assert soup.decode() == self.document_for("<b>I wish I was bold.</b>")
1145 | 
1146 |     def test_wrap_extracts_tag_from_elsewhere(self):
1147 |         soup = self.soup("<b></b>I wish I was bold.")
1148 |         soup.b.next_sibling.wrap(soup.b)
1149 |         assert soup.decode() == self.document_for("<b>I wish I was bold.</b>")
1150 | 
1151 |     def test_wrap_puts_new_contents_at_the_end(self):
1152 |         soup = self.soup("<b>I like being bold.</b>I wish I was bold.")
1153 |         soup.b.next_sibling.wrap(soup.b)
1154 |         assert 2 == len(soup.b.contents)
1155 |         assert soup.decode() == self.document_for(
1156 |             "<b>I like being bold.I wish I was bold.</b>"
1157 |         )
1158 | 
1159 |     def test_extract(self):
1160 |         soup = self.soup(
1161 |             '<html><body>Some content. <div id="nav">Nav crap</div> More content.</body></html>')
1162 | 
1163 |         assert len(soup.body.contents) == 3
1164 |         extracted = soup.find(id="nav").extract()
1165 | 
1166 |         assert soup.decode() == "<html><body>Some content.  More content.</body></html>"
1167 |         assert extracted.decode() == '<div id="nav">Nav crap</div>'
1168 | 
1169 |         # The extracted tag is now an orphan.
1170 |         assert len(soup.body.contents) == 2
1171 |         assert extracted.parent == None
1172 |         assert extracted.previous_element == None
1173 |         assert extracted.next_element.next_element == None
1174 | 
1175 |         # The gap where the extracted tag used to be has been mended.
1176 |         content_1 = soup.find(string="Some content. ")
1177 |         content_2 = soup.find(string=" More content.")
1178 |         assert content_1.next_element == content_2
1179 |         assert content_1.next_sibling == content_2
1180 |         assert content_2.previous_element == content_1
1181 |         assert content_2.previous_sibling == content_1
1182 | 
1183 |     def test_extract_distinguishes_between_identical_strings(self):
1184 |         soup = self.soup("<a>foo</a><b>bar</b>")
1185 |         foo_1 = soup.a.string
1186 |         bar_1 = soup.b.string
1187 |         foo_2 = soup.new_string("foo")
1188 |         bar_2 = soup.new_string("bar")
1189 |         soup.a.append(foo_2)
1190 |         soup.b.append(bar_2)
1191 | 
1192 |         # Now there are two identical strings in the <a> tag, and two
1193 |         # in the <b> tag. Let's remove the first "foo" and the second
1194 |         # "bar".
1195 |         foo_1.extract()
1196 |         bar_2.extract()
1197 |         assert foo_2 == soup.a.string
1198 |         assert bar_2 == soup.b.string
1199 | 
1200 |     def test_extract_multiples_of_same_tag(self):
1201 |         soup = self.soup("""
1202 | <html>
1203 | <head>
1204 | <script>foo</script>
1205 | </head>
1206 | <body>
1207 |  <script>bar</script>
1208 |  <a></a>
1209 | </body>
1210 | <script>baz</script>
1211 | </html>""")
1212 |         [soup.script.extract() for i in soup.find_all("script")]
1213 |         assert "<body>\n\n<a></a>\n</body>" == str(soup.body)
1214 | 
1215 | 
1216 |     def test_extract_works_when_element_is_surrounded_by_identical_strings(self):
1217 |         soup = self.soup(
1218 |  '<html>\n'
1219 |  '<body>hi</body>\n'
1220 |  '</html>')
1221 |         soup.find('body').extract()
1222 |         assert None == soup.find('body')
1223 | 
1224 | 
1225 |     def test_clear(self):
1226 |         """Tag.clear()"""
1227 |         soup = self.soup("<p><a>String <em>Italicized</em></a> and another</p>")
1228 |         # clear using extract()
1229 |         a = soup.a
1230 |         soup.p.clear()
1231 |         assert len(soup.p.contents) == 0
1232 |         assert hasattr(a, "contents")
1233 | 
1234 |         # clear using decompose()
1235 |         em = a.em
1236 |         a.clear(decompose=True)
1237 |         assert 0 == len(em.contents)
1238 | 
1239 |        
1240 |     def test_decompose(self):
1241 |         # Test PageElement.decompose() and PageElement.decomposed
1242 |         soup = self.soup("<p><a>String <em>Italicized</em></a></p><p>Another para</p>")
1243 |         p1, p2 = soup.find_all('p')
1244 |         a = p1.a
1245 |         text = p1.em.string
1246 |         for i in [p1, p2, a, text]:
1247 |             assert False == i.decomposed
1248 | 
1249 |         # This sets p1 and everything beneath it to decomposed.
1250 |         p1.decompose()
1251 |         for i in [p1, a, text]:
1252 |             assert True == i.decomposed
1253 |         # p2 is unaffected.
1254 |         assert False == p2.decomposed
1255 |             
1256 |     def test_string_set(self):
1257 |         """Tag.string = 'string'"""
1258 |         soup = self.soup("<a></a> <b><c></c></b>")
1259 |         soup.a.string = "foo"
1260 |         assert soup.a.contents == ["foo"]
1261 |         soup.b.string = "bar"
1262 |         assert soup.b.contents == ["bar"]
1263 | 
1264 |     def test_string_set_does_not_affect_original_string(self):
1265 |         soup = self.soup("<a><b>foo</b><c>bar</c>")
1266 |         soup.b.string = soup.c.string
1267 |         assert soup.a.encode() == b"<a><b>bar</b><c>bar</c></a>"
1268 | 
1269 |     def test_set_string_preserves_class_of_string(self):
1270 |         soup = self.soup("<a></a>")
1271 |         cdata = CData("foo")
1272 |         soup.a.string = cdata
1273 |         assert isinstance(soup.a.string, CData)
1274 | 
1275 | 
1276 | class TestDeprecatedArguments(SoupTest):
1277 | 
1278 |     @pytest.mark.parametrize(
1279 |         "method_name", [
1280 |             "find", "find_all", "find_parent", "find_parents",
1281 |             "find_next", "find_all_next", "find_previous",
1282 |             "find_all_previous", "find_next_sibling", "find_next_siblings",
1283 |             "find_previous_sibling", "find_previous_siblings",
1284 |         ]
1285 |     )
1286 |     def test_find_type_method_string(self, method_name):
1287 |         soup = self.soup("<a>some</a><b>markup</b>")
1288 |         method = getattr(soup.b, method_name)
1289 |         with warnings.catch_warnings(record=True) as w:
1290 |             method(text='markup')
1291 |             [warning] = w
1292 |             assert warning.filename == __file__
1293 |             msg = str(warning.message)
1294 |             assert msg == "The 'text' argument to find()-type methods is deprecated. Use 'string' instead."
1295 | 
1296 |     def test_soupstrainer_constructor_string(self):
1297 |         with warnings.catch_warnings(record=True) as w:
1298 |             strainer = SoupStrainer(text="text")
1299 |             assert strainer.text == 'text'
1300 |             [warning] = w
1301 |             msg = str(warning.message)
1302 |             assert warning.filename == __file__
1303 |             assert msg == "The 'text' argument to the SoupStrainer constructor is deprecated. Use 'string' instead."
1304 | 
1305 | 
```
Page 141/168FirstPrevNextLast