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

```python
   1 | # encoding: utf-8
   2 | """Helper classes for tests."""
   3 | 
   4 | # Use of this source code is governed by the MIT license.
   5 | __license__ = "MIT"
   6 | 
   7 | import pickle
   8 | import copy
   9 | import functools
  10 | import warnings
  11 | import pytest
  12 | from bs4 import BeautifulSoup
  13 | from bs4.element import (
  14 |     CharsetMetaAttributeValue,
  15 |     Comment,
  16 |     ContentMetaAttributeValue,
  17 |     Doctype,
  18 |     PYTHON_SPECIFIC_ENCODINGS,
  19 |     SoupStrainer,
  20 |     Script,
  21 |     Stylesheet,
  22 |     Tag
  23 | )
  24 | 
  25 | from bs4.builder import (
  26 |     DetectsXMLParsedAsHTML,
  27 |     HTMLParserTreeBuilder,
  28 |     XMLParsedAsHTMLWarning,
  29 | )
  30 | default_builder = HTMLParserTreeBuilder
  31 | 
  32 | # Some tests depend on specific third-party libraries. We use
  33 | # @pytest.mark.skipIf on the following conditionals to skip them
  34 | # if the libraries are not installed.
  35 | try:
  36 |     from soupsieve import SelectorSyntaxError
  37 |     SOUP_SIEVE_PRESENT = True
  38 | except ImportError:
  39 |     SOUP_SIEVE_PRESENT = False
  40 | 
  41 | try:
  42 |     import html5lib
  43 |     HTML5LIB_PRESENT = True
  44 | except ImportError:
  45 |     HTML5LIB_PRESENT = False
  46 | 
  47 | try:
  48 |     import lxml.etree
  49 |     LXML_PRESENT = True
  50 |     LXML_VERSION = lxml.etree.LXML_VERSION
  51 | except ImportError:
  52 |     LXML_PRESENT = False
  53 |     LXML_VERSION = (0,)
  54 | 
  55 | BAD_DOCUMENT = """A bare string
  56 | <!DOCTYPE xsl:stylesheet SYSTEM "htmlent.dtd">
  57 | <!DOCTYPE xsl:stylesheet PUBLIC "htmlent.dtd">
  58 | <div><![CDATA[A CDATA section where it doesn't belong]]></div>
  59 | <div><svg><![CDATA[HTML5 does allow CDATA sections in SVG]]></svg></div>
  60 | <div>A <meta> tag</div>
  61 | <div>A <br> tag that supposedly has contents.</br></div>
  62 | <div>AT&T</div>
  63 | <div><textarea>Within a textarea, markup like <b> tags and <&<&amp; should be treated as literal</textarea></div>
  64 | <div><script>if (i < 2) { alert("<b>Markup within script tags should be treated as literal.</b>"); }</script></div>
  65 | <div>This numeric entity is missing the final semicolon: <x t="pi&#241ata"></div>
  66 | <div><a href="http://example.com/</a> that attribute value never got closed</div>
  67 | <div><a href="foo</a>, </a><a href="bar">that attribute value was closed by the subsequent tag</a></div>
  68 | <! This document starts with a bogus declaration ><div>a</div>
  69 | <div>This document contains <!an incomplete declaration <div>(do you see it?)</div>
  70 | <div>This document ends with <!an incomplete declaration
  71 | <div><a style={height:21px;}>That attribute value was bogus</a></div>
  72 | <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">The doctype is invalid because it contains extra whitespace
  73 | <div><table><td nowrap>That boolean attribute had no value</td></table></div>
  74 | <div>Here's a nonexistent entity: &#foo; (do you see it?)</div>
  75 | <div>This document ends before the entity finishes: &gt
  76 | <div><p>Paragraphs shouldn't contain block display elements, but this one does: <dl><dt>you see?</dt></p>
  77 | <b b="20" a="1" b="10" a="2" a="3" a="4">Multiple values for the same attribute.</b>
  78 | <div><table><tr><td>Here's a table</td></tr></table></div>
  79 | <div><table id="1"><tr><td>Here's a nested table:<table id="2"><tr><td>foo</td></tr></table></td></div>
  80 | <div>This tag contains nothing but whitespace: <b>    </b></div>
  81 | <div><blockquote><p><b>This p tag is cut off by</blockquote></p>the end of the blockquote tag</div>
  82 | <div><table><div>This table contains bare markup</div></table></div>
  83 | <div><div id="1">\n <a href="link1">This link is never closed.\n</div>\n<div id="2">\n <div id="3">\n   <a href="link2">This link is closed.</a>\n  </div>\n</div></div>
  84 | <div>This document contains a <!DOCTYPE surprise>surprise doctype</div>
  85 | <div><a><B><Cd><EFG>Mixed case tags are folded to lowercase</efg></CD></b></A></div>
  86 | <div><our\u2603>Tag name contains Unicode characters</our\u2603></div>
  87 | <div><a \u2603="snowman">Attribute name contains Unicode characters</a></div>
  88 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  89 | """
  90 | 
  91 | 
  92 | class SoupTest(object):
  93 | 
  94 |     @property
  95 |     def default_builder(self):
  96 |         return default_builder
  97 | 
  98 |     def soup(self, markup, **kwargs):
  99 |         """Build a Beautiful Soup object from markup."""
 100 |         builder = kwargs.pop('builder', self.default_builder)
 101 |         return BeautifulSoup(markup, builder=builder, **kwargs)
 102 | 
 103 |     def document_for(self, markup, **kwargs):
 104 |         """Turn an HTML fragment into a document.
 105 | 
 106 |         The details depend on the builder.
 107 |         """
 108 |         return self.default_builder(**kwargs).test_fragment_to_document(markup)
 109 |    
 110 |     def assert_soup(self, to_parse, compare_parsed_to=None):
 111 |         """Parse some markup using Beautiful Soup and verify that
 112 |         the output markup is as expected.
 113 |         """
 114 |         builder = self.default_builder
 115 |         obj = BeautifulSoup(to_parse, builder=builder)
 116 |         if compare_parsed_to is None:
 117 |             compare_parsed_to = to_parse
 118 | 
 119 |         # Verify that the documents come out the same.
 120 |         assert obj.decode() == self.document_for(compare_parsed_to)
 121 | 
 122 |         # Also run some checks on the BeautifulSoup object itself:
 123 | 
 124 |         # Verify that every tag that was opened was eventually closed.
 125 | 
 126 |         # There are no tags in the open tag counter.
 127 |         assert all(v==0 for v in list(obj.open_tag_counter.values()))
 128 | 
 129 |         # The only tag in the tag stack is the one for the root
 130 |         # document.
 131 |         assert [obj.ROOT_TAG_NAME] == [x.name for x in obj.tagStack]
 132 | 
 133 |     assertSoupEquals = assert_soup
 134 |         
 135 |     def assertConnectedness(self, element):
 136 |         """Ensure that next_element and previous_element are properly
 137 |         set for all descendants of the given element.
 138 |         """
 139 |         earlier = None
 140 |         for e in element.descendants:
 141 |             if earlier:
 142 |                 assert e == earlier.next_element
 143 |                 assert earlier == e.previous_element
 144 |             earlier = e
 145 | 
 146 |     def linkage_validator(self, el, _recursive_call=False):
 147 |         """Ensure proper linkage throughout the document."""
 148 |         descendant = None
 149 |         # Document element should have no previous element or previous sibling.
 150 |         # It also shouldn't have a next sibling.
 151 |         if el.parent is None:
 152 |             assert el.previous_element is None,\
 153 |                 "Bad previous_element\nNODE: {}\nPREV: {}\nEXPECTED: {}".format(
 154 |                     el, el.previous_element, None
 155 |                 )
 156 |             assert el.previous_sibling is None,\
 157 |                 "Bad previous_sibling\nNODE: {}\nPREV: {}\nEXPECTED: {}".format(
 158 |                     el, el.previous_sibling, None
 159 |                 )
 160 |             assert el.next_sibling is None,\
 161 |                 "Bad next_sibling\nNODE: {}\nNEXT: {}\nEXPECTED: {}".format(
 162 |                     el, el.next_sibling, None
 163 |                 )
 164 | 
 165 |         idx = 0
 166 |         child = None
 167 |         last_child = None
 168 |         last_idx = len(el.contents) - 1
 169 |         for child in el.contents:
 170 |             descendant = None
 171 | 
 172 |             # Parent should link next element to their first child
 173 |             # That child should have no previous sibling
 174 |             if idx == 0:
 175 |                 if el.parent is not None:
 176 |                     assert el.next_element is child,\
 177 |                        "Bad next_element\nNODE: {}\nNEXT: {}\nEXPECTED: {}".format(
 178 |                             el, el.next_element, child
 179 |                         )
 180 |                     assert child.previous_element is el,\
 181 |                        "Bad previous_element\nNODE: {}\nPREV: {}\nEXPECTED: {}".format(
 182 |                             child, child.previous_element, el
 183 |                         )
 184 |                     assert child.previous_sibling is None,\
 185 |                        "Bad previous_sibling\nNODE: {}\nPREV {}\nEXPECTED: {}".format(
 186 |                             child, child.previous_sibling, None
 187 |                         )
 188 | 
 189 |             # If not the first child, previous index should link as sibling to this index
 190 |             # Previous element should match the last index or the last bubbled up descendant
 191 |             else:
 192 |                 assert child.previous_sibling is el.contents[idx - 1],\
 193 |                     "Bad previous_sibling\nNODE: {}\nPREV {}\nEXPECTED {}".format(
 194 |                         child, child.previous_sibling, el.contents[idx - 1]
 195 |                     )
 196 |                 assert el.contents[idx - 1].next_sibling is child,\
 197 |                     "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format(
 198 |                         el.contents[idx - 1], el.contents[idx - 1].next_sibling, child
 199 |                     )
 200 | 
 201 |                 if last_child is not None:
 202 |                     assert child.previous_element is last_child,\
 203 |                         "Bad previous_element\nNODE: {}\nPREV {}\nEXPECTED {}\nCONTENTS {}".format(
 204 |                             child, child.previous_element, last_child, child.parent.contents
 205 |                         )
 206 |                     assert last_child.next_element is child,\
 207 |                         "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format(
 208 |                             last_child, last_child.next_element, child
 209 |                         )
 210 | 
 211 |             if isinstance(child, Tag) and child.contents:
 212 |                 descendant = self.linkage_validator(child, True)
 213 |                 # A bubbled up descendant should have no next siblings
 214 |                 assert descendant.next_sibling is None,\
 215 |                     "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format(
 216 |                         descendant, descendant.next_sibling, None
 217 |                     )
 218 | 
 219 |             # Mark last child as either the bubbled up descendant or the current child
 220 |             if descendant is not None:
 221 |                 last_child = descendant
 222 |             else:
 223 |                 last_child = child
 224 | 
 225 |             # If last child, there are non next siblings
 226 |             if idx == last_idx:
 227 |                 assert child.next_sibling is None,\
 228 |                     "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format(
 229 |                         child, child.next_sibling, None
 230 |                     )
 231 |             idx += 1
 232 | 
 233 |         child = descendant if descendant is not None else child
 234 |         if child is None:
 235 |             child = el
 236 | 
 237 |         if not _recursive_call and child is not None:
 238 |             target = el
 239 |             while True:
 240 |                 if target is None:
 241 |                     assert child.next_element is None, \
 242 |                         "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format(
 243 |                             child, child.next_element, None
 244 |                         )
 245 |                     break
 246 |                 elif target.next_sibling is not None:
 247 |                     assert child.next_element is target.next_sibling, \
 248 |                         "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format(
 249 |                             child, child.next_element, target.next_sibling
 250 |                         )
 251 |                     break
 252 |                 target = target.parent
 253 | 
 254 |             # We are done, so nothing to return
 255 |             return None
 256 |         else:
 257 |             # Return the child to the recursive caller
 258 |             return child
 259 | 
 260 |     def assert_selects(self, tags, should_match):
 261 |         """Make sure that the given tags have the correct text.
 262 | 
 263 |         This is used in tests that define a bunch of tags, each
 264 |         containing a single string, and then select certain strings by
 265 |         some mechanism.
 266 |         """
 267 |         assert [tag.string for tag in tags] == should_match
 268 | 
 269 |     def assert_selects_ids(self, tags, should_match):
 270 |         """Make sure that the given tags have the correct IDs.
 271 | 
 272 |         This is used in tests that define a bunch of tags, each
 273 |         containing a single string, and then select certain strings by
 274 |         some mechanism.
 275 |         """
 276 |         assert [tag['id'] for tag in tags] == should_match
 277 | 
 278 | 
 279 | class TreeBuilderSmokeTest(object):
 280 |     # Tests that are common to HTML and XML tree builders.
 281 | 
 282 |     @pytest.mark.parametrize(
 283 |         "multi_valued_attributes",
 284 |         [None, {}, dict(b=['class']), {'*': ['notclass']}]
 285 |     )
 286 |     def test_attribute_not_multi_valued(self, multi_valued_attributes):
 287 |         markup = '<html xmlns="http://www.w3.org/1999/xhtml"><a class="a b c"></html>'
 288 |         soup = self.soup(markup, multi_valued_attributes=multi_valued_attributes)
 289 |         assert soup.a['class'] == 'a b c'
 290 | 
 291 |     @pytest.mark.parametrize(
 292 |         "multi_valued_attributes", [dict(a=['class']), {'*': ['class']}]
 293 |     )
 294 |     def test_attribute_multi_valued(self, multi_valued_attributes):
 295 |         markup = '<a class="a b c">'
 296 |         soup = self.soup(
 297 |             markup, multi_valued_attributes=multi_valued_attributes
 298 |         )
 299 |         assert soup.a['class'] == ['a', 'b', 'c']
 300 | 
 301 |     def test_invalid_doctype(self):
 302 |         markup = '<![if word]>content<![endif]>'
 303 |         markup = '<!DOCTYPE html]ff>'
 304 |         soup = self.soup(markup)
 305 | 
 306 | class HTMLTreeBuilderSmokeTest(TreeBuilderSmokeTest):
 307 | 
 308 |     """A basic test of a treebuilder's competence.
 309 | 
 310 |     Any HTML treebuilder, present or future, should be able to pass
 311 |     these tests. With invalid markup, there's room for interpretation,
 312 |     and different parsers can handle it differently. But with the
 313 |     markup in these tests, there's not much room for interpretation.
 314 |     """
 315 | 
 316 |     def test_empty_element_tags(self):
 317 |         """Verify that all HTML4 and HTML5 empty element (aka void element) tags
 318 |         are handled correctly.
 319 |         """
 320 |         for name in [
 321 |                 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr',
 322 |                 'spacer', 'frame'
 323 |         ]:
 324 |             soup = self.soup("")
 325 |             new_tag = soup.new_tag(name)
 326 |             assert new_tag.is_empty_element == True
 327 | 
 328 |     def test_special_string_containers(self):
 329 |         soup = self.soup(
 330 |             "<style>Some CSS</style><script>Some Javascript</script>"
 331 |         )
 332 |         assert isinstance(soup.style.string, Stylesheet)
 333 |         assert isinstance(soup.script.string, Script)
 334 | 
 335 |         soup = self.soup(
 336 |             "<style><!--Some CSS--></style>"
 337 |         )
 338 |         assert isinstance(soup.style.string, Stylesheet)
 339 |         # The contents of the style tag resemble an HTML comment, but
 340 |         # it's not treated as a comment.
 341 |         assert soup.style.string == "<!--Some CSS-->"
 342 |         assert isinstance(soup.style.string, Stylesheet)
 343 |         
 344 |     def test_pickle_and_unpickle_identity(self):
 345 |         # Pickling a tree, then unpickling it, yields a tree identical
 346 |         # to the original.
 347 |         tree = self.soup("<a><b>foo</a>")
 348 |         dumped = pickle.dumps(tree, 2)
 349 |         loaded = pickle.loads(dumped)
 350 |         assert loaded.__class__ == BeautifulSoup
 351 |         assert loaded.decode() == tree.decode()
 352 | 
 353 |     def assertDoctypeHandled(self, doctype_fragment):
 354 |         """Assert that a given doctype string is handled correctly."""
 355 |         doctype_str, soup = self._document_with_doctype(doctype_fragment)
 356 | 
 357 |         # Make sure a Doctype object was created.
 358 |         doctype = soup.contents[0]
 359 |         assert doctype.__class__ == Doctype
 360 |         assert doctype == doctype_fragment
 361 |         assert soup.encode("utf8")[:len(doctype_str)] == doctype_str
 362 | 
 363 |         # Make sure that the doctype was correctly associated with the
 364 |         # parse tree and that the rest of the document parsed.
 365 |         assert soup.p.contents[0] == 'foo'
 366 | 
 367 |     def _document_with_doctype(self, doctype_fragment, doctype_string="DOCTYPE"):
 368 |         """Generate and parse a document with the given doctype."""
 369 |         doctype = '<!%s %s>' % (doctype_string, doctype_fragment)
 370 |         markup = doctype + '\n<p>foo</p>'
 371 |         soup = self.soup(markup)
 372 |         return doctype.encode("utf8"), soup
 373 | 
 374 |     def test_normal_doctypes(self):
 375 |         """Make sure normal, everyday HTML doctypes are handled correctly."""
 376 |         self.assertDoctypeHandled("html")
 377 |         self.assertDoctypeHandled(
 378 |             'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"')
 379 | 
 380 |     def test_empty_doctype(self):
 381 |         soup = self.soup("<!DOCTYPE>")
 382 |         doctype = soup.contents[0]
 383 |         assert "" == doctype.strip()
 384 | 
 385 |     def test_mixed_case_doctype(self):
 386 |         # A lowercase or mixed-case doctype becomes a Doctype.
 387 |         for doctype_fragment in ("doctype", "DocType"):
 388 |             doctype_str, soup = self._document_with_doctype(
 389 |                 "html", doctype_fragment
 390 |             )
 391 | 
 392 |             # Make sure a Doctype object was created and that the DOCTYPE
 393 |             # is uppercase.
 394 |             doctype = soup.contents[0]
 395 |             assert doctype.__class__ == Doctype
 396 |             assert doctype == "html"
 397 |             assert soup.encode("utf8")[:len(doctype_str)] == b"<!DOCTYPE html>"
 398 | 
 399 |             # Make sure that the doctype was correctly associated with the
 400 |             # parse tree and that the rest of the document parsed.
 401 |             assert soup.p.contents[0] == 'foo'
 402 |         
 403 |     def test_public_doctype_with_url(self):
 404 |         doctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"'
 405 |         self.assertDoctypeHandled(doctype)
 406 | 
 407 |     def test_system_doctype(self):
 408 |         self.assertDoctypeHandled('foo SYSTEM "http://www.example.com/"')
 409 | 
 410 |     def test_namespaced_system_doctype(self):
 411 |         # We can handle a namespaced doctype with a system ID.
 412 |         self.assertDoctypeHandled('xsl:stylesheet SYSTEM "htmlent.dtd"')
 413 | 
 414 |     def test_namespaced_public_doctype(self):
 415 |         # Test a namespaced doctype with a public id.
 416 |         self.assertDoctypeHandled('xsl:stylesheet PUBLIC "htmlent.dtd"')
 417 | 
 418 |     def test_real_xhtml_document(self):
 419 |         """A real XHTML document should come out more or less the same as it went in."""
 420 |         markup = b"""<?xml version="1.0" encoding="utf-8"?>
 421 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
 422 | <html xmlns="http://www.w3.org/1999/xhtml">
 423 | <head><title>Hello.</title></head>
 424 | <body>Goodbye.</body>
 425 | </html>"""
 426 |         with warnings.catch_warnings(record=True) as w:
 427 |             soup = self.soup(markup)
 428 |         assert soup.encode("utf-8").replace(b"\n", b"") == markup.replace(b"\n", b"")
 429 | 
 430 |         # No warning was issued about parsing an XML document as HTML,
 431 |         # because XHTML is both.
 432 |         assert w == []
 433 | 
 434 | 
 435 |     def test_namespaced_html(self):
 436 |         # When a namespaced XML document is parsed as HTML it should
 437 |         # be treated as HTML with weird tag names.
 438 |         markup = b"""<ns1:foo>content</ns1:foo><ns1:foo/><ns2:foo/>"""
 439 |         with warnings.catch_warnings(record=True) as w:
 440 |             soup = self.soup(markup)
 441 | 
 442 |         assert 2 == len(soup.find_all("ns1:foo"))
 443 |             
 444 |         # n.b. no "you're parsing XML as HTML" warning was given
 445 |         # because there was no XML declaration.
 446 |         assert [] == w
 447 | 
 448 |     def test_detect_xml_parsed_as_html(self):
 449 |         # A warning is issued when parsing an XML document as HTML,
 450 |         # but basic stuff should still work.
 451 |         markup = b"""<?xml version="1.0" encoding="utf-8"?><tag>string</tag>"""
 452 |         with warnings.catch_warnings(record=True) as w:
 453 |             soup = self.soup(markup)
 454 |             assert soup.tag.string == 'string'
 455 |         [warning] = w
 456 |         assert isinstance(warning.message, XMLParsedAsHTMLWarning)
 457 |         assert str(warning.message) == XMLParsedAsHTMLWarning.MESSAGE
 458 | 
 459 |         # NOTE: the warning is not issued if the document appears to
 460 |         # be XHTML (tested with test_real_xhtml_document in the
 461 |         # superclass) or if there is no XML declaration (tested with
 462 |         # test_namespaced_html in the superclass).
 463 |         
 464 |     def test_processing_instruction(self):
 465 |         # We test both Unicode and bytestring to verify that
 466 |         # process_markup correctly sets processing_instruction_class
 467 |         # even when the markup is already Unicode and there is no
 468 |         # need to process anything.
 469 |         markup = """<?PITarget PIContent?>"""
 470 |         soup = self.soup(markup)
 471 |         assert markup == soup.decode()
 472 | 
 473 |         markup = b"""<?PITarget PIContent?>"""
 474 |         soup = self.soup(markup)
 475 |         assert markup == soup.encode("utf8")
 476 | 
 477 |     def test_deepcopy(self):
 478 |         """Make sure you can copy the tree builder.
 479 | 
 480 |         This is important because the builder is part of a
 481 |         BeautifulSoup object, and we want to be able to copy that.
 482 |         """
 483 |         copy.deepcopy(self.default_builder)
 484 | 
 485 |     def test_p_tag_is_never_empty_element(self):
 486 |         """A <p> tag is never designated as an empty-element tag.
 487 | 
 488 |         Even if the markup shows it as an empty-element tag, it
 489 |         shouldn't be presented that way.
 490 |         """
 491 |         soup = self.soup("<p/>")
 492 |         assert not soup.p.is_empty_element
 493 |         assert str(soup.p) == "<p></p>"
 494 | 
 495 |     def test_unclosed_tags_get_closed(self):
 496 |         """A tag that's not closed by the end of the document should be closed.
 497 | 
 498 |         This applies to all tags except empty-element tags.
 499 |         """
 500 |         self.assert_soup("<p>", "<p></p>")
 501 |         self.assert_soup("<b>", "<b></b>")
 502 | 
 503 |         self.assert_soup("<br>", "<br/>")
 504 | 
 505 |     def test_br_is_always_empty_element_tag(self):
 506 |         """A <br> tag is designated as an empty-element tag.
 507 | 
 508 |         Some parsers treat <br></br> as one <br/> tag, some parsers as
 509 |         two tags, but it should always be an empty-element tag.
 510 |         """
 511 |         soup = self.soup("<br></br>")
 512 |         assert soup.br.is_empty_element
 513 |         assert str(soup.br) == "<br/>"
 514 | 
 515 |     def test_nested_formatting_elements(self):
 516 |         self.assert_soup("<em><em></em></em>")
 517 | 
 518 |     def test_double_head(self):
 519 |         html = '''<!DOCTYPE html>
 520 | <html>
 521 | <head>
 522 | <title>Ordinary HEAD element test</title>
 523 | </head>
 524 | <script type="text/javascript">
 525 | alert("Help!");
 526 | </script>
 527 | <body>
 528 | Hello, world!
 529 | </body>
 530 | </html>
 531 | '''
 532 |         soup = self.soup(html)
 533 |         assert "text/javascript" == soup.find('script')['type']
 534 | 
 535 |     def test_comment(self):
 536 |         # Comments are represented as Comment objects.
 537 |         markup = "<p>foo<!--foobar-->baz</p>"
 538 |         self.assert_soup(markup)
 539 | 
 540 |         soup = self.soup(markup)
 541 |         comment = soup.find(string="foobar")
 542 |         assert comment.__class__ == Comment
 543 | 
 544 |         # The comment is properly integrated into the tree.
 545 |         foo = soup.find(string="foo")
 546 |         assert comment == foo.next_element
 547 |         baz = soup.find(string="baz")
 548 |         assert comment == baz.previous_element
 549 | 
 550 |     def test_preserved_whitespace_in_pre_and_textarea(self):
 551 |         """Whitespace must be preserved in <pre> and <textarea> tags,
 552 |         even if that would mean not prettifying the markup.
 553 |         """
 554 |         pre_markup = "<pre>a   z</pre>\n"
 555 |         textarea_markup = "<textarea> woo\nwoo  </textarea>\n"
 556 |         self.assert_soup(pre_markup)
 557 |         self.assert_soup(textarea_markup)
 558 | 
 559 |         soup = self.soup(pre_markup)
 560 |         assert soup.pre.prettify() == pre_markup
 561 | 
 562 |         soup = self.soup(textarea_markup)
 563 |         assert soup.textarea.prettify() == textarea_markup
 564 | 
 565 |         soup = self.soup("<textarea></textarea>")
 566 |         assert soup.textarea.prettify() == "<textarea></textarea>\n"
 567 | 
 568 |     def test_nested_inline_elements(self):
 569 |         """Inline elements can be nested indefinitely."""
 570 |         b_tag = "<b>Inside a B tag</b>"
 571 |         self.assert_soup(b_tag)
 572 | 
 573 |         nested_b_tag = "<p>A <i>nested <b>tag</b></i></p>"
 574 |         self.assert_soup(nested_b_tag)
 575 | 
 576 |         double_nested_b_tag = "<p>A <a>doubly <i>nested <b>tag</b></i></a></p>"
 577 |         self.assert_soup(nested_b_tag)
 578 | 
 579 |     def test_nested_block_level_elements(self):
 580 |         """Block elements can be nested."""
 581 |         soup = self.soup('<blockquote><p><b>Foo</b></p></blockquote>')
 582 |         blockquote = soup.blockquote
 583 |         assert blockquote.p.b.string == 'Foo'
 584 |         assert blockquote.b.string == 'Foo'
 585 | 
 586 |     def test_correctly_nested_tables(self):
 587 |         """One table can go inside another one."""
 588 |         markup = ('<table id="1">'
 589 |                   '<tr>'
 590 |                   "<td>Here's another table:"
 591 |                   '<table id="2">'
 592 |                   '<tr><td>foo</td></tr>'
 593 |                   '</table></td>')
 594 | 
 595 |         self.assert_soup(
 596 |             markup,
 597 |             '<table id="1"><tr><td>Here\'s another table:'
 598 |             '<table id="2"><tr><td>foo</td></tr></table>'
 599 |             '</td></tr></table>')
 600 | 
 601 |         self.assert_soup(
 602 |             "<table><thead><tr><td>Foo</td></tr></thead>"
 603 |             "<tbody><tr><td>Bar</td></tr></tbody>"
 604 |             "<tfoot><tr><td>Baz</td></tr></tfoot></table>")
 605 | 
 606 |     def test_multivalued_attribute_with_whitespace(self):
 607 |         # Whitespace separating the values of a multi-valued attribute
 608 |         # should be ignored.
 609 | 
 610 |         markup = '<div class=" foo bar	 "></a>'
 611 |         soup = self.soup(markup)
 612 |         assert ['foo', 'bar'] == soup.div['class']
 613 | 
 614 |         # If you search by the literal name of the class it's like the whitespace
 615 |         # wasn't there.
 616 |         assert soup.div == soup.find('div', class_="foo bar")
 617 |         
 618 |     def test_deeply_nested_multivalued_attribute(self):
 619 |         # html5lib can set the attributes of the same tag many times
 620 |         # as it rearranges the tree. This has caused problems with
 621 |         # multivalued attributes.
 622 |         markup = '<table><div><div class="css"></div></div></table>'
 623 |         soup = self.soup(markup)
 624 |         assert ["css"] == soup.div.div['class']
 625 | 
 626 |     def test_multivalued_attribute_on_html(self):
 627 |         # html5lib uses a different API to set the attributes ot the
 628 |         # <html> tag. This has caused problems with multivalued
 629 |         # attributes.
 630 |         markup = '<html class="a b"></html>'
 631 |         soup = self.soup(markup)
 632 |         assert ["a", "b"] == soup.html['class']
 633 | 
 634 |     def test_angle_brackets_in_attribute_values_are_escaped(self):
 635 |         self.assert_soup('<a b="<a>"></a>', '<a b="&lt;a&gt;"></a>')
 636 | 
 637 |     def test_strings_resembling_character_entity_references(self):
 638 |         # "&T" and "&p" look like incomplete character entities, but they are
 639 |         # not.
 640 |         self.assert_soup(
 641 |             "<p>&bull; AT&T is in the s&p 500</p>",
 642 |             "<p>\u2022 AT&amp;T is in the s&amp;p 500</p>"
 643 |         )
 644 | 
 645 |     def test_apos_entity(self):
 646 |         self.assert_soup(
 647 |             "<p>Bob&apos;s Bar</p>",
 648 |             "<p>Bob's Bar</p>",
 649 |         )
 650 |         
 651 |     def test_entities_in_foreign_document_encoding(self):
 652 |         # &#147; and &#148; are invalid numeric entities referencing
 653 |         # Windows-1252 characters. &#45; references a character common
 654 |         # to Windows-1252 and Unicode, and &#9731; references a
 655 |         # character only found in Unicode.
 656 |         #
 657 |         # All of these entities should be converted to Unicode
 658 |         # characters.
 659 |         markup = "<p>&#147;Hello&#148; &#45;&#9731;</p>"
 660 |         soup = self.soup(markup)
 661 |         assert "“Hello” -☃" == soup.p.string
 662 |         
 663 |     def test_entities_in_attributes_converted_to_unicode(self):
 664 |         expect = '<p id="pi\N{LATIN SMALL LETTER N WITH TILDE}ata"></p>'
 665 |         self.assert_soup('<p id="pi&#241;ata"></p>', expect)
 666 |         self.assert_soup('<p id="pi&#xf1;ata"></p>', expect)
 667 |         self.assert_soup('<p id="pi&#Xf1;ata"></p>', expect)
 668 |         self.assert_soup('<p id="pi&ntilde;ata"></p>', expect)
 669 | 
 670 |     def test_entities_in_text_converted_to_unicode(self):
 671 |         expect = '<p>pi\N{LATIN SMALL LETTER N WITH TILDE}ata</p>'
 672 |         self.assert_soup("<p>pi&#241;ata</p>", expect)
 673 |         self.assert_soup("<p>pi&#xf1;ata</p>", expect)
 674 |         self.assert_soup("<p>pi&#Xf1;ata</p>", expect)
 675 |         self.assert_soup("<p>pi&ntilde;ata</p>", expect)
 676 | 
 677 |     def test_quot_entity_converted_to_quotation_mark(self):
 678 |         self.assert_soup("<p>I said &quot;good day!&quot;</p>",
 679 |                               '<p>I said "good day!"</p>')
 680 | 
 681 |     def test_out_of_range_entity(self):
 682 |         expect = "\N{REPLACEMENT CHARACTER}"
 683 |         self.assert_soup("&#10000000000000;", expect)
 684 |         self.assert_soup("&#x10000000000000;", expect)
 685 |         self.assert_soup("&#1000000000;", expect)
 686 |        
 687 |     def test_multipart_strings(self):
 688 |         "Mostly to prevent a recurrence of a bug in the html5lib treebuilder."
 689 |         soup = self.soup("<html><h2>\nfoo</h2><p></p></html>")
 690 |         assert "p" == soup.h2.string.next_element.name
 691 |         assert "p" == soup.p.name
 692 |         self.assertConnectedness(soup)
 693 | 
 694 |     def test_empty_element_tags(self):
 695 |         """Verify consistent handling of empty-element tags,
 696 |         no matter how they come in through the markup.
 697 |         """
 698 |         self.assert_soup('<br/><br/><br/>', "<br/><br/><br/>")
 699 |         self.assert_soup('<br /><br /><br />', "<br/><br/><br/>")
 700 |         
 701 |     def test_head_tag_between_head_and_body(self):
 702 |         "Prevent recurrence of a bug in the html5lib treebuilder."
 703 |         content = """<html><head></head>
 704 |   <link></link>
 705 |   <body>foo</body>
 706 | </html>
 707 | """
 708 |         soup = self.soup(content)
 709 |         assert soup.html.body is not None
 710 |         self.assertConnectedness(soup)
 711 | 
 712 |     def test_multiple_copies_of_a_tag(self):
 713 |         "Prevent recurrence of a bug in the html5lib treebuilder."
 714 |         content = """<!DOCTYPE html>
 715 | <html>
 716 |  <body>
 717 |    <article id="a" >
 718 |    <div><a href="1"></div>
 719 |    <footer>
 720 |      <a href="2"></a>
 721 |    </footer>
 722 |   </article>
 723 |   </body>
 724 | </html>
 725 | """
 726 |         soup = self.soup(content)
 727 |         self.assertConnectedness(soup.article)
 728 | 
 729 |     def test_basic_namespaces(self):
 730 |         """Parsers don't need to *understand* namespaces, but at the
 731 |         very least they should not choke on namespaces or lose
 732 |         data."""
 733 | 
 734 |         markup = b'<html xmlns="http://www.w3.org/1999/xhtml" xmlns:mathml="http://www.w3.org/1998/Math/MathML" xmlns:svg="http://www.w3.org/2000/svg"><head></head><body><mathml:msqrt>4</mathml:msqrt><b svg:fill="red"></b></body></html>'
 735 |         soup = self.soup(markup)
 736 |         assert markup == soup.encode()
 737 |         html = soup.html
 738 |         assert 'http://www.w3.org/1999/xhtml' == soup.html['xmlns']
 739 |         assert 'http://www.w3.org/1998/Math/MathML' == soup.html['xmlns:mathml']
 740 |         assert 'http://www.w3.org/2000/svg' == soup.html['xmlns:svg']
 741 | 
 742 |     def test_multivalued_attribute_value_becomes_list(self):
 743 |         markup = b'<a class="foo bar">'
 744 |         soup = self.soup(markup)
 745 |         assert ['foo', 'bar'] == soup.a['class']
 746 |         
 747 |     #
 748 |     # Generally speaking, tests below this point are more tests of
 749 |     # Beautiful Soup than tests of the tree builders. But parsers are
 750 |     # weird, so we run these tests separately for every tree builder
 751 |     # to detect any differences between them.
 752 |     #
 753 | 
 754 |     def test_can_parse_unicode_document(self):
 755 |         # A seemingly innocuous document... but it's in Unicode! And
 756 |         # it contains characters that can't be represented in the
 757 |         # encoding found in the  declaration! The horror!
 758 |         markup = '<html><head><meta encoding="euc-jp"></head><body>Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!</body>'
 759 |         soup = self.soup(markup)
 760 |         assert 'Sacr\xe9 bleu!' == soup.body.string
 761 | 
 762 |     def test_soupstrainer(self):
 763 |         """Parsers should be able to work with SoupStrainers."""
 764 |         strainer = SoupStrainer("b")
 765 |         soup = self.soup("A <b>bold</b> <meta/> <i>statement</i>",
 766 |                          parse_only=strainer)
 767 |         assert soup.decode() == "<b>bold</b>"
 768 | 
 769 |     def test_single_quote_attribute_values_become_double_quotes(self):
 770 |         self.assert_soup("<foo attr='bar'></foo>",
 771 |                               '<foo attr="bar"></foo>')
 772 | 
 773 |     def test_attribute_values_with_nested_quotes_are_left_alone(self):
 774 |         text = """<foo attr='bar "brawls" happen'>a</foo>"""
 775 |         self.assert_soup(text)
 776 | 
 777 |     def test_attribute_values_with_double_nested_quotes_get_quoted(self):
 778 |         text = """<foo attr='bar "brawls" happen'>a</foo>"""
 779 |         soup = self.soup(text)
 780 |         soup.foo['attr'] = 'Brawls happen at "Bob\'s Bar"'
 781 |         self.assert_soup(
 782 |             soup.foo.decode(),
 783 |             """<foo attr="Brawls happen at &quot;Bob\'s Bar&quot;">a</foo>""")
 784 | 
 785 |     def test_ampersand_in_attribute_value_gets_escaped(self):
 786 |         self.assert_soup('<this is="really messed up & stuff"></this>',
 787 |                               '<this is="really messed up &amp; stuff"></this>')
 788 | 
 789 |         self.assert_soup(
 790 |             '<a href="http://example.org?a=1&b=2;3">foo</a>',
 791 |             '<a href="http://example.org?a=1&amp;b=2;3">foo</a>')
 792 | 
 793 |     def test_escaped_ampersand_in_attribute_value_is_left_alone(self):
 794 |         self.assert_soup('<a href="http://example.org?a=1&amp;b=2;3"></a>')
 795 | 
 796 |     def test_entities_in_strings_converted_during_parsing(self):
 797 |         # Both XML and HTML entities are converted to Unicode characters
 798 |         # during parsing.
 799 |         text = "<p>&lt;&lt;sacr&eacute;&#32;bleu!&gt;&gt;</p>"
 800 |         expected = "<p>&lt;&lt;sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</p>"
 801 |         self.assert_soup(text, expected)
 802 | 
 803 |     def test_smart_quotes_converted_on_the_way_in(self):
 804 |         # Microsoft smart quotes are converted to Unicode characters during
 805 |         # parsing.
 806 |         quote = b"<p>\x91Foo\x92</p>"
 807 |         soup = self.soup(quote)
 808 |         assert soup.p.string == "\N{LEFT SINGLE QUOTATION MARK}Foo\N{RIGHT SINGLE QUOTATION MARK}"
 809 | 
 810 |     def test_non_breaking_spaces_converted_on_the_way_in(self):
 811 |         soup = self.soup("<a>&nbsp;&nbsp;</a>")
 812 |         assert soup.a.string == "\N{NO-BREAK SPACE}" * 2
 813 | 
 814 |     def test_entities_converted_on_the_way_out(self):
 815 |         text = "<p>&lt;&lt;sacr&eacute;&#32;bleu!&gt;&gt;</p>"
 816 |         expected = "<p>&lt;&lt;sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</p>".encode("utf-8")
 817 |         soup = self.soup(text)
 818 |         assert soup.p.encode("utf-8") == expected
 819 | 
 820 |     def test_real_iso_8859_document(self):
 821 |         # Smoke test of interrelated functionality, using an
 822 |         # easy-to-understand document.
 823 | 
 824 |         # Here it is in Unicode. Note that it claims to be in ISO-8859-1.
 825 |         unicode_html = '<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-type"/></head><body><p>Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!</p></body></html>'
 826 | 
 827 |         # That's because we're going to encode it into ISO-8859-1,
 828 |         # and use that to test.
 829 |         iso_latin_html = unicode_html.encode("iso-8859-1")
 830 | 
 831 |         # Parse the ISO-8859-1 HTML.
 832 |         soup = self.soup(iso_latin_html)
 833 | 
 834 |         # Encode it to UTF-8.
 835 |         result = soup.encode("utf-8")
 836 | 
 837 |         # What do we expect the result to look like? Well, it would
 838 |         # look like unicode_html, except that the META tag would say
 839 |         # UTF-8 instead of ISO-8859-1.
 840 |         expected = unicode_html.replace("ISO-8859-1", "utf-8")
 841 | 
 842 |         # And, of course, it would be in UTF-8, not Unicode.
 843 |         expected = expected.encode("utf-8")
 844 | 
 845 |         # Ta-da!
 846 |         assert result == expected
 847 | 
 848 |     def test_real_shift_jis_document(self):
 849 |         # Smoke test to make sure the parser can handle a document in
 850 |         # Shift-JIS encoding, without choking.
 851 |         shift_jis_html = (
 852 |             b'<html><head></head><body><pre>'
 853 |             b'\x82\xb1\x82\xea\x82\xcdShift-JIS\x82\xc5\x83R\x81[\x83f'
 854 |             b'\x83B\x83\x93\x83O\x82\xb3\x82\xea\x82\xbd\x93\xfa\x96{\x8c'
 855 |             b'\xea\x82\xcc\x83t\x83@\x83C\x83\x8b\x82\xc5\x82\xb7\x81B'
 856 |             b'</pre></body></html>')
 857 |         unicode_html = shift_jis_html.decode("shift-jis")
 858 |         soup = self.soup(unicode_html)
 859 | 
 860 |         # Make sure the parse tree is correctly encoded to various
 861 |         # encodings.
 862 |         assert soup.encode("utf-8") == unicode_html.encode("utf-8")
 863 |         assert soup.encode("euc_jp") == unicode_html.encode("euc_jp")
 864 | 
 865 |     def test_real_hebrew_document(self):
 866 |         # A real-world test to make sure we can convert ISO-8859-9 (a
 867 |         # Hebrew encoding) to UTF-8.
 868 |         hebrew_document = b'<html><head><title>Hebrew (ISO 8859-8) in Visual Directionality</title></head><body><h1>Hebrew (ISO 8859-8) in Visual Directionality</h1>\xed\xe5\xec\xf9</body></html>'
 869 |         soup = self.soup(
 870 |             hebrew_document, from_encoding="iso8859-8")
 871 |         # Some tree builders call it iso8859-8, others call it iso-8859-9.
 872 |         # That's not a difference we really care about.
 873 |         assert soup.original_encoding in ('iso8859-8', 'iso-8859-8')
 874 |         assert soup.encode('utf-8') == (
 875 |             hebrew_document.decode("iso8859-8").encode("utf-8")
 876 |         )
 877 | 
 878 |     def test_meta_tag_reflects_current_encoding(self):
 879 |         # Here's the <meta> tag saying that a document is
 880 |         # encoded in Shift-JIS.
 881 |         meta_tag = ('<meta content="text/html; charset=x-sjis" '
 882 |                     'http-equiv="Content-type"/>')
 883 | 
 884 |         # Here's a document incorporating that meta tag.
 885 |         shift_jis_html = (
 886 |             '<html><head>\n%s\n'
 887 |             '<meta http-equiv="Content-language" content="ja"/>'
 888 |             '</head><body>Shift-JIS markup goes here.') % meta_tag
 889 |         soup = self.soup(shift_jis_html)
 890 | 
 891 |         # Parse the document, and the charset is seemingly unaffected.
 892 |         parsed_meta = soup.find('meta', {'http-equiv': 'Content-type'})
 893 |         content = parsed_meta['content']
 894 |         assert 'text/html; charset=x-sjis' == content
 895 | 
 896 |         # But that value is actually a ContentMetaAttributeValue object.
 897 |         assert isinstance(content, ContentMetaAttributeValue)
 898 | 
 899 |         # And it will take on a value that reflects its current
 900 |         # encoding.
 901 |         assert 'text/html; charset=utf8' == content.encode("utf8")
 902 | 
 903 |         # For the rest of the story, see TestSubstitutions in
 904 |         # test_tree.py.
 905 | 
 906 |     def test_html5_style_meta_tag_reflects_current_encoding(self):
 907 |         # Here's the <meta> tag saying that a document is
 908 |         # encoded in Shift-JIS.
 909 |         meta_tag = ('<meta id="encoding" charset="x-sjis" />')
 910 | 
 911 |         # Here's a document incorporating that meta tag.
 912 |         shift_jis_html = (
 913 |             '<html><head>\n%s\n'
 914 |             '<meta http-equiv="Content-language" content="ja"/>'
 915 |             '</head><body>Shift-JIS markup goes here.') % meta_tag
 916 |         soup = self.soup(shift_jis_html)
 917 | 
 918 |         # Parse the document, and the charset is seemingly unaffected.
 919 |         parsed_meta = soup.find('meta', id="encoding")
 920 |         charset = parsed_meta['charset']
 921 |         assert 'x-sjis' == charset
 922 | 
 923 |         # But that value is actually a CharsetMetaAttributeValue object.
 924 |         assert isinstance(charset, CharsetMetaAttributeValue)
 925 | 
 926 |         # And it will take on a value that reflects its current
 927 |         # encoding.
 928 |         assert 'utf8' == charset.encode("utf8")
 929 | 
 930 |     def test_python_specific_encodings_not_used_in_charset(self):
 931 |         # You can encode an HTML document using a Python-specific
 932 |         # encoding, but that encoding won't be mentioned _inside_ the
 933 |         # resulting document. Instead, the document will appear to
 934 |         # have no encoding.
 935 |         for markup in [
 936 |             b'<meta charset="utf8"></head>'
 937 |             b'<meta id="encoding" charset="utf-8" />'
 938 |         ]:
 939 |             soup = self.soup(markup)
 940 |             for encoding in PYTHON_SPECIFIC_ENCODINGS:
 941 |                 if encoding in (
 942 |                     'idna', 'mbcs', 'oem', 'undefined',
 943 |                     'string_escape', 'string-escape'
 944 |                 ):
 945 |                     # For one reason or another, these will raise an
 946 |                     # exception if we actually try to use them, so don't
 947 |                     # bother.
 948 |                     continue
 949 |                 encoded = soup.encode(encoding)
 950 |                 assert b'meta charset=""' in encoded
 951 |                 assert encoding.encode("ascii") not in encoded
 952 |         
 953 |     def test_tag_with_no_attributes_can_have_attributes_added(self):
 954 |         data = self.soup("<a>text</a>")
 955 |         data.a['foo'] = 'bar'
 956 |         assert '<a foo="bar">text</a>' == data.a.decode()
 957 | 
 958 |     def test_closing_tag_with_no_opening_tag(self):
 959 |         # Without BeautifulSoup.open_tag_counter, the </span> tag will
 960 |         # cause _popToTag to be called over and over again as we look
 961 |         # for a <span> tag that wasn't there. The result is that 'text2'
 962 |         # will show up outside the body of the document.
 963 |         soup = self.soup("<body><div><p>text1</p></span>text2</div></body>")
 964 |         assert "<body><div><p>text1</p>text2</div></body>" == soup.body.decode()
 965 |         
 966 |     def test_worst_case(self):
 967 |         """Test the worst case (currently) for linking issues."""
 968 | 
 969 |         soup = self.soup(BAD_DOCUMENT)
 970 |         self.linkage_validator(soup)
 971 | 
 972 | 
 973 | class XMLTreeBuilderSmokeTest(TreeBuilderSmokeTest):
 974 | 
 975 |     def test_pickle_and_unpickle_identity(self):
 976 |         # Pickling a tree, then unpickling it, yields a tree identical
 977 |         # to the original.
 978 |         tree = self.soup("<a><b>foo</a>")
 979 |         dumped = pickle.dumps(tree, 2)
 980 |         loaded = pickle.loads(dumped)
 981 |         assert loaded.__class__ == BeautifulSoup
 982 |         assert loaded.decode() == tree.decode()
 983 | 
 984 |     def test_docstring_generated(self):
 985 |         soup = self.soup("<root/>")
 986 |         assert soup.encode() == b'<?xml version="1.0" encoding="utf-8"?>\n<root/>'
 987 | 
 988 |     def test_xml_declaration(self):
 989 |         markup = b"""<?xml version="1.0" encoding="utf8"?>\n<foo/>"""
 990 |         soup = self.soup(markup)
 991 |         assert markup == soup.encode("utf8")
 992 | 
 993 |     def test_python_specific_encodings_not_used_in_xml_declaration(self):
 994 |         # You can encode an XML document using a Python-specific
 995 |         # encoding, but that encoding won't be mentioned _inside_ the
 996 |         # resulting document.
 997 |         markup = b"""<?xml version="1.0"?>\n<foo/>"""
 998 |         soup = self.soup(markup)
 999 |         for encoding in PYTHON_SPECIFIC_ENCODINGS:
1000 |             if encoding in (
1001 |                 'idna', 'mbcs', 'oem', 'undefined',
1002 |                 'string_escape', 'string-escape'
1003 |             ):
1004 |                 # For one reason or another, these will raise an
1005 |                 # exception if we actually try to use them, so don't
1006 |                 # bother.
1007 |                 continue
1008 |             encoded = soup.encode(encoding)
1009 |             assert b'<?xml version="1.0"?>' in encoded
1010 |             assert encoding.encode("ascii") not in encoded
1011 | 
1012 |     def test_processing_instruction(self):
1013 |         markup = b"""<?xml version="1.0" encoding="utf8"?>\n<?PITarget PIContent?>"""
1014 |         soup = self.soup(markup)
1015 |         assert markup == soup.encode("utf8")
1016 | 
1017 |     def test_real_xhtml_document(self):
1018 |         """A real XHTML document should come out *exactly* the same as it went in."""
1019 |         markup = b"""<?xml version="1.0" encoding="utf-8"?>
1020 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
1021 | <html xmlns="http://www.w3.org/1999/xhtml">
1022 | <head><title>Hello.</title></head>
1023 | <body>Goodbye.</body>
1024 | </html>"""
1025 |         soup = self.soup(markup)
1026 |         assert soup.encode("utf-8") == markup
1027 |        
1028 |     def test_nested_namespaces(self):
1029 |         doc = b"""<?xml version="1.0" encoding="utf-8"?>
1030 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1031 | <parent xmlns="http://ns1/">
1032 | <child xmlns="http://ns2/" xmlns:ns3="http://ns3/">
1033 | <grandchild ns3:attr="value" xmlns="http://ns4/"/>
1034 | </child>
1035 | </parent>"""
1036 |         soup = self.soup(doc)
1037 |         assert doc == soup.encode()
1038 |         
1039 |     def test_formatter_processes_script_tag_for_xml_documents(self):
1040 |         doc = """
1041 |   <script type="text/javascript">
1042 |   </script>
1043 | """
1044 |         soup = BeautifulSoup(doc, "lxml-xml")
1045 |         # lxml would have stripped this while parsing, but we can add
1046 |         # it later.
1047 |         soup.script.string = 'console.log("< < hey > > ");'
1048 |         encoded = soup.encode()
1049 |         assert b"&lt; &lt; hey &gt; &gt;" in encoded
1050 | 
1051 |     def test_can_parse_unicode_document(self):
1052 |         markup = '<?xml version="1.0" encoding="euc-jp"><root>Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!</root>'
1053 |         soup = self.soup(markup)
1054 |         assert 'Sacr\xe9 bleu!' == soup.root.string
1055 | 
1056 |     def test_can_parse_unicode_document_begining_with_bom(self):
1057 |         markup = '\N{BYTE ORDER MARK}<?xml version="1.0" encoding="euc-jp"><root>Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!</root>'
1058 |         soup = self.soup(markup)
1059 |         assert 'Sacr\xe9 bleu!' == soup.root.string
1060 |         
1061 |     def test_popping_namespaced_tag(self):
1062 |         markup = '<rss xmlns:dc="foo"><dc:creator>b</dc:creator><dc:date>2012-07-02T20:33:42Z</dc:date><dc:rights>c</dc:rights><image>d</image></rss>'
1063 |         soup = self.soup(markup)
1064 |         assert str(soup.rss) == markup
1065 | 
1066 |     def test_docstring_includes_correct_encoding(self):
1067 |         soup = self.soup("<root/>")
1068 |         assert soup.encode("latin1") == b'<?xml version="1.0" encoding="latin1"?>\n<root/>'
1069 | 
1070 |     def test_large_xml_document(self):
1071 |         """A large XML document should come out the same as it went in."""
1072 |         markup = (b'<?xml version="1.0" encoding="utf-8"?>\n<root>'
1073 |                   + b'0' * (2**12)
1074 |                   + b'</root>')
1075 |         soup = self.soup(markup)
1076 |         assert soup.encode("utf-8") == markup
1077 | 
1078 |     def test_tags_are_empty_element_if_and_only_if_they_are_empty(self):
1079 |         self.assert_soup("<p>", "<p/>")
1080 |         self.assert_soup("<p>foo</p>")
1081 | 
1082 |     def test_namespaces_are_preserved(self):
1083 |         markup = '<root xmlns:a="http://example.com/" xmlns:b="http://example.net/"><a:foo>This tag is in the a namespace</a:foo><b:foo>This tag is in the b namespace</b:foo></root>'
1084 |         soup = self.soup(markup)
1085 |         root = soup.root
1086 |         assert "http://example.com/" == root['xmlns:a']
1087 |         assert "http://example.net/" == root['xmlns:b']
1088 | 
1089 |     def test_closing_namespaced_tag(self):
1090 |         markup = '<p xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>20010504</dc:date></p>'
1091 |         soup = self.soup(markup)
1092 |         assert str(soup.p) == markup
1093 | 
1094 |     def test_namespaced_attributes(self):
1095 |         markup = '<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><bar xsi:schemaLocation="http://www.example.com"/></foo>'
1096 |         soup = self.soup(markup)
1097 |         assert str(soup.foo) == markup
1098 | 
1099 |     def test_namespaced_attributes_xml_namespace(self):
1100 |         markup = '<foo xml:lang="fr">bar</foo>'
1101 |         soup = self.soup(markup)
1102 |         assert str(soup.foo) == markup
1103 | 
1104 |     def test_find_by_prefixed_name(self):
1105 |         doc = """<?xml version="1.0" encoding="utf-8"?>
1106 | <Document xmlns="http://example.com/ns0"
1107 |     xmlns:ns1="http://example.com/ns1"
1108 |     xmlns:ns2="http://example.com/ns2">
1109 |     <ns1:tag>foo</ns1:tag>
1110 |     <ns1:tag>bar</ns1:tag>
1111 |     <ns2:tag key="value">baz</ns2:tag>
1112 | </Document>
1113 | """
1114 |         soup = self.soup(doc)
1115 | 
1116 |         # There are three <tag> tags.
1117 |         assert 3 == len(soup.find_all('tag'))
1118 | 
1119 |         # But two of them are ns1:tag and one of them is ns2:tag.
1120 |         assert 2 == len(soup.find_all('ns1:tag'))
1121 |         assert 1 == len(soup.find_all('ns2:tag'))
1122 |         
1123 |         assert 1, len(soup.find_all('ns2:tag', key='value'))
1124 |         assert 3, len(soup.find_all(['ns1:tag', 'ns2:tag']))
1125 |         
1126 |     def test_copy_tag_preserves_namespace(self):
1127 |         xml = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1128 | <w:document xmlns:w="http://example.com/ns0"/>"""
1129 |     
1130 |         soup = self.soup(xml)
1131 |         tag = soup.document
1132 |         duplicate = copy.copy(tag)
1133 | 
1134 |         # The two tags have the same namespace prefix.
1135 |         assert tag.prefix == duplicate.prefix
1136 | 
1137 |     def test_worst_case(self):
1138 |         """Test the worst case (currently) for linking issues."""
1139 | 
1140 |         soup = self.soup(BAD_DOCUMENT)
1141 |         self.linkage_validator(soup)
1142 | 
1143 | 
1144 | class HTML5TreeBuilderSmokeTest(HTMLTreeBuilderSmokeTest):
1145 |     """Smoke test for a tree builder that supports HTML5."""
1146 | 
1147 |     def test_real_xhtml_document(self):
1148 |         # Since XHTML is not HTML5, HTML5 parsers are not tested to handle
1149 |         # XHTML documents in any particular way.
1150 |         pass
1151 | 
1152 |     def test_html_tags_have_namespace(self):
1153 |         markup = "<a>"
1154 |         soup = self.soup(markup)
1155 |         assert "http://www.w3.org/1999/xhtml" == soup.a.namespace
1156 | 
1157 |     def test_svg_tags_have_namespace(self):
1158 |         markup = '<svg><circle/></svg>'
1159 |         soup = self.soup(markup)
1160 |         namespace = "http://www.w3.org/2000/svg"
1161 |         assert namespace == soup.svg.namespace
1162 |         assert namespace == soup.circle.namespace
1163 | 
1164 | 
1165 |     def test_mathml_tags_have_namespace(self):
1166 |         markup = '<math><msqrt>5</msqrt></math>'
1167 |         soup = self.soup(markup)
1168 |         namespace = 'http://www.w3.org/1998/Math/MathML'
1169 |         assert namespace == soup.math.namespace
1170 |         assert namespace == soup.msqrt.namespace
1171 | 
1172 |     def test_xml_declaration_becomes_comment(self):
1173 |         markup = '<?xml version="1.0" encoding="utf-8"?><html></html>'
1174 |         soup = self.soup(markup)
1175 |         assert isinstance(soup.contents[0], Comment)
1176 |         assert soup.contents[0] == '?xml version="1.0" encoding="utf-8"?'
1177 |         assert "html" == soup.contents[0].next_element.name
1178 | 
```
Page 142/168FirstPrevNextLast