#
tokens: 45669/50000 2/808 files (page 84/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 84 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/werkzeug/utils.py:
--------------------------------------------------------------------------------

```python
  1 | from __future__ import annotations
  2 | 
  3 | import io
  4 | import mimetypes
  5 | import os
  6 | import pkgutil
  7 | import re
  8 | import sys
  9 | import typing as t
 10 | import unicodedata
 11 | from datetime import datetime
 12 | from time import time
 13 | from urllib.parse import quote
 14 | from zlib import adler32
 15 | 
 16 | from markupsafe import escape
 17 | 
 18 | from ._internal import _DictAccessorProperty
 19 | from ._internal import _missing
 20 | from ._internal import _TAccessorValue
 21 | from .datastructures import Headers
 22 | from .exceptions import NotFound
 23 | from .exceptions import RequestedRangeNotSatisfiable
 24 | from .security import safe_join
 25 | from .wsgi import wrap_file
 26 | 
 27 | if t.TYPE_CHECKING:
 28 |     from _typeshed.wsgi import WSGIEnvironment
 29 | 
 30 |     from .wrappers.request import Request
 31 |     from .wrappers.response import Response
 32 | 
 33 | _T = t.TypeVar("_T")
 34 | 
 35 | _entity_re = re.compile(r"&([^;]+);")
 36 | _filename_ascii_strip_re = re.compile(r"[^A-Za-z0-9_.-]")
 37 | _windows_device_files = {
 38 |     "CON",
 39 |     "PRN",
 40 |     "AUX",
 41 |     "NUL",
 42 |     *(f"COM{i}" for i in range(10)),
 43 |     *(f"LPT{i}" for i in range(10)),
 44 | }
 45 | 
 46 | 
 47 | class cached_property(property, t.Generic[_T]):
 48 |     """A :func:`property` that is only evaluated once. Subsequent access
 49 |     returns the cached value. Setting the property sets the cached
 50 |     value. Deleting the property clears the cached value, accessing it
 51 |     again will evaluate it again.
 52 | 
 53 |     .. code-block:: python
 54 | 
 55 |         class Example:
 56 |             @cached_property
 57 |             def value(self):
 58 |                 # calculate something important here
 59 |                 return 42
 60 | 
 61 |         e = Example()
 62 |         e.value  # evaluates
 63 |         e.value  # uses cache
 64 |         e.value = 16  # sets cache
 65 |         del e.value  # clears cache
 66 | 
 67 |     If the class defines ``__slots__``, it must add ``_cache_{name}`` as
 68 |     a slot. Alternatively, it can add ``__dict__``, but that's usually
 69 |     not desirable.
 70 | 
 71 |     .. versionchanged:: 2.1
 72 |         Works with ``__slots__``.
 73 | 
 74 |     .. versionchanged:: 2.0
 75 |         ``del obj.name`` clears the cached value.
 76 |     """
 77 | 
 78 |     def __init__(
 79 |         self,
 80 |         fget: t.Callable[[t.Any], _T],
 81 |         name: str | None = None,
 82 |         doc: str | None = None,
 83 |     ) -> None:
 84 |         super().__init__(fget, doc=doc)
 85 |         self.__name__ = name or fget.__name__
 86 |         self.slot_name = f"_cache_{self.__name__}"
 87 |         self.__module__ = fget.__module__
 88 | 
 89 |     def __set__(self, obj: object, value: _T) -> None:
 90 |         if hasattr(obj, "__dict__"):
 91 |             obj.__dict__[self.__name__] = value
 92 |         else:
 93 |             setattr(obj, self.slot_name, value)
 94 | 
 95 |     def __get__(self, obj: object, type: type = None) -> _T:  # type: ignore
 96 |         if obj is None:
 97 |             return self  # type: ignore
 98 | 
 99 |         obj_dict = getattr(obj, "__dict__", None)
100 | 
101 |         if obj_dict is not None:
102 |             value: _T = obj_dict.get(self.__name__, _missing)
103 |         else:
104 |             value = getattr(obj, self.slot_name, _missing)  # type: ignore[arg-type]
105 | 
106 |         if value is _missing:
107 |             value = self.fget(obj)  # type: ignore
108 | 
109 |             if obj_dict is not None:
110 |                 obj.__dict__[self.__name__] = value
111 |             else:
112 |                 setattr(obj, self.slot_name, value)
113 | 
114 |         return value
115 | 
116 |     def __delete__(self, obj: object) -> None:
117 |         if hasattr(obj, "__dict__"):
118 |             del obj.__dict__[self.__name__]
119 |         else:
120 |             setattr(obj, self.slot_name, _missing)
121 | 
122 | 
123 | class environ_property(_DictAccessorProperty[_TAccessorValue]):
124 |     """Maps request attributes to environment variables. This works not only
125 |     for the Werkzeug request object, but also any other class with an
126 |     environ attribute:
127 | 
128 |     >>> class Test(object):
129 |     ...     environ = {'key': 'value'}
130 |     ...     test = environ_property('key')
131 |     >>> var = Test()
132 |     >>> var.test
133 |     'value'
134 | 
135 |     If you pass it a second value it's used as default if the key does not
136 |     exist, the third one can be a converter that takes a value and converts
137 |     it.  If it raises :exc:`ValueError` or :exc:`TypeError` the default value
138 |     is used. If no default value is provided `None` is used.
139 | 
140 |     Per default the property is read only.  You have to explicitly enable it
141 |     by passing ``read_only=False`` to the constructor.
142 |     """
143 | 
144 |     read_only = True
145 | 
146 |     def lookup(self, obj: Request) -> WSGIEnvironment:
147 |         return obj.environ
148 | 
149 | 
150 | class header_property(_DictAccessorProperty[_TAccessorValue]):
151 |     """Like `environ_property` but for headers."""
152 | 
153 |     def lookup(self, obj: Request | Response) -> Headers:
154 |         return obj.headers
155 | 
156 | 
157 | # https://cgit.freedesktop.org/xdg/shared-mime-info/tree/freedesktop.org.xml.in
158 | # https://www.iana.org/assignments/media-types/media-types.xhtml
159 | # Types listed in the XDG mime info that have a charset in the IANA registration.
160 | _charset_mimetypes = {
161 |     "application/ecmascript",
162 |     "application/javascript",
163 |     "application/sql",
164 |     "application/xml",
165 |     "application/xml-dtd",
166 |     "application/xml-external-parsed-entity",
167 | }
168 | 
169 | 
170 | def get_content_type(mimetype: str, charset: str) -> str:
171 |     """Returns the full content type string with charset for a mimetype.
172 | 
173 |     If the mimetype represents text, the charset parameter will be
174 |     appended, otherwise the mimetype is returned unchanged.
175 | 
176 |     :param mimetype: The mimetype to be used as content type.
177 |     :param charset: The charset to be appended for text mimetypes.
178 |     :return: The content type.
179 | 
180 |     .. versionchanged:: 0.15
181 |         Any type that ends with ``+xml`` gets a charset, not just those
182 |         that start with ``application/``. Known text types such as
183 |         ``application/javascript`` are also given charsets.
184 |     """
185 |     if (
186 |         mimetype.startswith("text/")
187 |         or mimetype in _charset_mimetypes
188 |         or mimetype.endswith("+xml")
189 |     ):
190 |         mimetype += f"; charset={charset}"
191 | 
192 |     return mimetype
193 | 
194 | 
195 | def secure_filename(filename: str) -> str:
196 |     r"""Pass it a filename and it will return a secure version of it.  This
197 |     filename can then safely be stored on a regular file system and passed
198 |     to :func:`os.path.join`.  The filename returned is an ASCII only string
199 |     for maximum portability.
200 | 
201 |     On windows systems the function also makes sure that the file is not
202 |     named after one of the special device files.
203 | 
204 |     >>> secure_filename("My cool movie.mov")
205 |     'My_cool_movie.mov'
206 |     >>> secure_filename("../../../etc/passwd")
207 |     'etc_passwd'
208 |     >>> secure_filename('i contain cool \xfcml\xe4uts.txt')
209 |     'i_contain_cool_umlauts.txt'
210 | 
211 |     The function might return an empty filename.  It's your responsibility
212 |     to ensure that the filename is unique and that you abort or
213 |     generate a random filename if the function returned an empty one.
214 | 
215 |     .. versionadded:: 0.5
216 | 
217 |     :param filename: the filename to secure
218 |     """
219 |     filename = unicodedata.normalize("NFKD", filename)
220 |     filename = filename.encode("ascii", "ignore").decode("ascii")
221 | 
222 |     for sep in os.sep, os.path.altsep:
223 |         if sep:
224 |             filename = filename.replace(sep, " ")
225 |     filename = str(_filename_ascii_strip_re.sub("", "_".join(filename.split()))).strip(
226 |         "._"
227 |     )
228 | 
229 |     # on nt a couple of special files are present in each folder.  We
230 |     # have to ensure that the target file is not such a filename.  In
231 |     # this case we prepend an underline
232 |     if (
233 |         os.name == "nt"
234 |         and filename
235 |         and filename.split(".")[0].upper() in _windows_device_files
236 |     ):
237 |         filename = f"_{filename}"
238 | 
239 |     return filename
240 | 
241 | 
242 | def redirect(
243 |     location: str, code: int = 302, Response: type[Response] | None = None
244 | ) -> Response:
245 |     """Returns a response object (a WSGI application) that, if called,
246 |     redirects the client to the target location. Supported codes are
247 |     301, 302, 303, 305, 307, and 308. 300 is not supported because
248 |     it's not a real redirect and 304 because it's the answer for a
249 |     request with a request with defined If-Modified-Since headers.
250 | 
251 |     .. versionadded:: 0.6
252 |        The location can now be a unicode string that is encoded using
253 |        the :func:`iri_to_uri` function.
254 | 
255 |     .. versionadded:: 0.10
256 |         The class used for the Response object can now be passed in.
257 | 
258 |     :param location: the location the response should redirect to.
259 |     :param code: the redirect status code. defaults to 302.
260 |     :param class Response: a Response class to use when instantiating a
261 |         response. The default is :class:`werkzeug.wrappers.Response` if
262 |         unspecified.
263 |     """
264 |     if Response is None:
265 |         from .wrappers import Response
266 | 
267 |     html_location = escape(location)
268 |     response = Response(  # type: ignore[misc]
269 |         "<!doctype html>\n"
270 |         "<html lang=en>\n"
271 |         "<title>Redirecting...</title>\n"
272 |         "<h1>Redirecting...</h1>\n"
273 |         "<p>You should be redirected automatically to the target URL: "
274 |         f'<a href="{html_location}">{html_location}</a>. If not, click the link.\n',
275 |         code,
276 |         mimetype="text/html",
277 |     )
278 |     response.headers["Location"] = location
279 |     return response
280 | 
281 | 
282 | def append_slash_redirect(environ: WSGIEnvironment, code: int = 308) -> Response:
283 |     """Redirect to the current URL with a slash appended.
284 | 
285 |     If the current URL is ``/user/42``, the redirect URL will be
286 |     ``42/``. When joined to the current URL during response
287 |     processing or by the browser, this will produce ``/user/42/``.
288 | 
289 |     The behavior is undefined if the path ends with a slash already. If
290 |     called unconditionally on a URL, it may produce a redirect loop.
291 | 
292 |     :param environ: Use the path and query from this WSGI environment
293 |         to produce the redirect URL.
294 |     :param code: the status code for the redirect.
295 | 
296 |     .. versionchanged:: 2.1
297 |         Produce a relative URL that only modifies the last segment.
298 |         Relevant when the current path has multiple segments.
299 | 
300 |     .. versionchanged:: 2.1
301 |         The default status code is 308 instead of 301. This preserves
302 |         the request method and body.
303 |     """
304 |     tail = environ["PATH_INFO"].rpartition("/")[2]
305 | 
306 |     if not tail:
307 |         new_path = "./"
308 |     else:
309 |         new_path = f"{tail}/"
310 | 
311 |     query_string = environ.get("QUERY_STRING")
312 | 
313 |     if query_string:
314 |         new_path = f"{new_path}?{query_string}"
315 | 
316 |     return redirect(new_path, code)
317 | 
318 | 
319 | def send_file(
320 |     path_or_file: os.PathLike[str] | str | t.IO[bytes],
321 |     environ: WSGIEnvironment,
322 |     mimetype: str | None = None,
323 |     as_attachment: bool = False,
324 |     download_name: str | None = None,
325 |     conditional: bool = True,
326 |     etag: bool | str = True,
327 |     last_modified: datetime | int | float | None = None,
328 |     max_age: None | (int | t.Callable[[str | None], int | None]) = None,
329 |     use_x_sendfile: bool = False,
330 |     response_class: type[Response] | None = None,
331 |     _root_path: os.PathLike[str] | str | None = None,
332 | ) -> Response:
333 |     """Send the contents of a file to the client.
334 | 
335 |     The first argument can be a file path or a file-like object. Paths
336 |     are preferred in most cases because Werkzeug can manage the file and
337 |     get extra information from the path. Passing a file-like object
338 |     requires that the file is opened in binary mode, and is mostly
339 |     useful when building a file in memory with :class:`io.BytesIO`.
340 | 
341 |     Never pass file paths provided by a user. The path is assumed to be
342 |     trusted, so a user could craft a path to access a file you didn't
343 |     intend. Use :func:`send_from_directory` to safely serve user-provided paths.
344 | 
345 |     If the WSGI server sets a ``file_wrapper`` in ``environ``, it is
346 |     used, otherwise Werkzeug's built-in wrapper is used. Alternatively,
347 |     if the HTTP server supports ``X-Sendfile``, ``use_x_sendfile=True``
348 |     will tell the server to send the given path, which is much more
349 |     efficient than reading it in Python.
350 | 
351 |     :param path_or_file: The path to the file to send, relative to the
352 |         current working directory if a relative path is given.
353 |         Alternatively, a file-like object opened in binary mode. Make
354 |         sure the file pointer is seeked to the start of the data.
355 |     :param environ: The WSGI environ for the current request.
356 |     :param mimetype: The MIME type to send for the file. If not
357 |         provided, it will try to detect it from the file name.
358 |     :param as_attachment: Indicate to a browser that it should offer to
359 |         save the file instead of displaying it.
360 |     :param download_name: The default name browsers will use when saving
361 |         the file. Defaults to the passed file name.
362 |     :param conditional: Enable conditional and range responses based on
363 |         request headers. Requires passing a file path and ``environ``.
364 |     :param etag: Calculate an ETag for the file, which requires passing
365 |         a file path. Can also be a string to use instead.
366 |     :param last_modified: The last modified time to send for the file,
367 |         in seconds. If not provided, it will try to detect it from the
368 |         file path.
369 |     :param max_age: How long the client should cache the file, in
370 |         seconds. If set, ``Cache-Control`` will be ``public``, otherwise
371 |         it will be ``no-cache`` to prefer conditional caching.
372 |     :param use_x_sendfile: Set the ``X-Sendfile`` header to let the
373 |         server to efficiently send the file. Requires support from the
374 |         HTTP server. Requires passing a file path.
375 |     :param response_class: Build the response using this class. Defaults
376 |         to :class:`~werkzeug.wrappers.Response`.
377 |     :param _root_path: Do not use. For internal use only. Use
378 |         :func:`send_from_directory` to safely send files under a path.
379 | 
380 |     .. versionchanged:: 2.0.2
381 |         ``send_file`` only sets a detected ``Content-Encoding`` if
382 |         ``as_attachment`` is disabled.
383 | 
384 |     .. versionadded:: 2.0
385 |         Adapted from Flask's implementation.
386 | 
387 |     .. versionchanged:: 2.0
388 |         ``download_name`` replaces Flask's ``attachment_filename``
389 |          parameter. If ``as_attachment=False``, it is passed with
390 |          ``Content-Disposition: inline`` instead.
391 | 
392 |     .. versionchanged:: 2.0
393 |         ``max_age`` replaces Flask's ``cache_timeout`` parameter.
394 |         ``conditional`` is enabled and ``max_age`` is not set by
395 |         default.
396 | 
397 |     .. versionchanged:: 2.0
398 |         ``etag`` replaces Flask's ``add_etags`` parameter. It can be a
399 |         string to use instead of generating one.
400 | 
401 |     .. versionchanged:: 2.0
402 |         If an encoding is returned when guessing ``mimetype`` from
403 |         ``download_name``, set the ``Content-Encoding`` header.
404 |     """
405 |     if response_class is None:
406 |         from .wrappers import Response
407 | 
408 |         response_class = Response
409 | 
410 |     path: str | None = None
411 |     file: t.IO[bytes] | None = None
412 |     size: int | None = None
413 |     mtime: float | None = None
414 |     headers = Headers()
415 | 
416 |     if isinstance(path_or_file, (os.PathLike, str)) or hasattr(
417 |         path_or_file, "__fspath__"
418 |     ):
419 |         path_or_file = t.cast("t.Union[os.PathLike[str], str]", path_or_file)
420 | 
421 |         # Flask will pass app.root_path, allowing its send_file wrapper
422 |         # to not have to deal with paths.
423 |         if _root_path is not None:
424 |             path = os.path.join(_root_path, path_or_file)
425 |         else:
426 |             path = os.path.abspath(path_or_file)
427 | 
428 |         stat = os.stat(path)
429 |         size = stat.st_size
430 |         mtime = stat.st_mtime
431 |     else:
432 |         file = path_or_file
433 | 
434 |     if download_name is None and path is not None:
435 |         download_name = os.path.basename(path)
436 | 
437 |     if mimetype is None:
438 |         if download_name is None:
439 |             raise TypeError(
440 |                 "Unable to detect the MIME type because a file name is"
441 |                 " not available. Either set 'download_name', pass a"
442 |                 " path instead of a file, or set 'mimetype'."
443 |             )
444 | 
445 |         mimetype, encoding = mimetypes.guess_type(download_name)
446 | 
447 |         if mimetype is None:
448 |             mimetype = "application/octet-stream"
449 | 
450 |         # Don't send encoding for attachments, it causes browsers to
451 |         # save decompress tar.gz files.
452 |         if encoding is not None and not as_attachment:
453 |             headers.set("Content-Encoding", encoding)
454 | 
455 |     if download_name is not None:
456 |         try:
457 |             download_name.encode("ascii")
458 |         except UnicodeEncodeError:
459 |             simple = unicodedata.normalize("NFKD", download_name)
460 |             simple = simple.encode("ascii", "ignore").decode("ascii")
461 |             # safe = RFC 5987 attr-char
462 |             quoted = quote(download_name, safe="!#$&+-.^_`|~")
463 |             names = {"filename": simple, "filename*": f"UTF-8''{quoted}"}
464 |         else:
465 |             names = {"filename": download_name}
466 | 
467 |         value = "attachment" if as_attachment else "inline"
468 |         headers.set("Content-Disposition", value, **names)
469 |     elif as_attachment:
470 |         raise TypeError(
471 |             "No name provided for attachment. Either set"
472 |             " 'download_name' or pass a path instead of a file."
473 |         )
474 | 
475 |     if use_x_sendfile and path is not None:
476 |         headers["X-Sendfile"] = path
477 |         data = None
478 |     else:
479 |         if file is None:
480 |             file = open(path, "rb")  # type: ignore
481 |         elif isinstance(file, io.BytesIO):
482 |             size = file.getbuffer().nbytes
483 |         elif isinstance(file, io.TextIOBase):
484 |             raise ValueError("Files must be opened in binary mode or use BytesIO.")
485 | 
486 |         data = wrap_file(environ, file)
487 | 
488 |     rv = response_class(
489 |         data, mimetype=mimetype, headers=headers, direct_passthrough=True
490 |     )
491 | 
492 |     if size is not None:
493 |         rv.content_length = size
494 | 
495 |     if last_modified is not None:
496 |         rv.last_modified = last_modified  # type: ignore
497 |     elif mtime is not None:
498 |         rv.last_modified = mtime  # type: ignore
499 | 
500 |     rv.cache_control.no_cache = True
501 | 
502 |     # Flask will pass app.get_send_file_max_age, allowing its send_file
503 |     # wrapper to not have to deal with paths.
504 |     if callable(max_age):
505 |         max_age = max_age(path)
506 | 
507 |     if max_age is not None:
508 |         if max_age > 0:
509 |             rv.cache_control.no_cache = None
510 |             rv.cache_control.public = True
511 | 
512 |         rv.cache_control.max_age = max_age
513 |         rv.expires = int(time() + max_age)  # type: ignore
514 | 
515 |     if isinstance(etag, str):
516 |         rv.set_etag(etag)
517 |     elif etag and path is not None:
518 |         check = adler32(path.encode()) & 0xFFFFFFFF
519 |         rv.set_etag(f"{mtime}-{size}-{check}")
520 | 
521 |     if conditional:
522 |         try:
523 |             rv = rv.make_conditional(environ, accept_ranges=True, complete_length=size)
524 |         except RequestedRangeNotSatisfiable:
525 |             if file is not None:
526 |                 file.close()
527 | 
528 |             raise
529 | 
530 |         # Some x-sendfile implementations incorrectly ignore the 304
531 |         # status code and send the file anyway.
532 |         if rv.status_code == 304:
533 |             rv.headers.pop("x-sendfile", None)
534 | 
535 |     return rv
536 | 
537 | 
538 | def send_from_directory(
539 |     directory: os.PathLike[str] | str,
540 |     path: os.PathLike[str] | str,
541 |     environ: WSGIEnvironment,
542 |     **kwargs: t.Any,
543 | ) -> Response:
544 |     """Send a file from within a directory using :func:`send_file`.
545 | 
546 |     This is a secure way to serve files from a folder, such as static
547 |     files or uploads. Uses :func:`~werkzeug.security.safe_join` to
548 |     ensure the path coming from the client is not maliciously crafted to
549 |     point outside the specified directory.
550 | 
551 |     If the final path does not point to an existing regular file,
552 |     returns a 404 :exc:`~werkzeug.exceptions.NotFound` error.
553 | 
554 |     :param directory: The directory that ``path`` must be located under. This *must not*
555 |         be a value provided by the client, otherwise it becomes insecure.
556 |     :param path: The path to the file to send, relative to ``directory``. This is the
557 |         part of the path provided by the client, which is checked for security.
558 |     :param environ: The WSGI environ for the current request.
559 |     :param kwargs: Arguments to pass to :func:`send_file`.
560 | 
561 |     .. versionadded:: 2.0
562 |         Adapted from Flask's implementation.
563 |     """
564 |     path_str = safe_join(os.fspath(directory), os.fspath(path))
565 | 
566 |     if path_str is None:
567 |         raise NotFound()
568 | 
569 |     # Flask will pass app.root_path, allowing its send_from_directory
570 |     # wrapper to not have to deal with paths.
571 |     if "_root_path" in kwargs:
572 |         path_str = os.path.join(kwargs["_root_path"], path_str)
573 | 
574 |     if not os.path.isfile(path_str):
575 |         raise NotFound()
576 | 
577 |     return send_file(path_str, environ, **kwargs)
578 | 
579 | 
580 | def import_string(import_name: str, silent: bool = False) -> t.Any:
581 |     """Imports an object based on a string.  This is useful if you want to
582 |     use import paths as endpoints or something similar.  An import path can
583 |     be specified either in dotted notation (``xml.sax.saxutils.escape``)
584 |     or with a colon as object delimiter (``xml.sax.saxutils:escape``).
585 | 
586 |     If `silent` is True the return value will be `None` if the import fails.
587 | 
588 |     :param import_name: the dotted name for the object to import.
589 |     :param silent: if set to `True` import errors are ignored and
590 |                    `None` is returned instead.
591 |     :return: imported object
592 |     """
593 |     import_name = import_name.replace(":", ".")
594 |     try:
595 |         try:
596 |             __import__(import_name)
597 |         except ImportError:
598 |             if "." not in import_name:
599 |                 raise
600 |         else:
601 |             return sys.modules[import_name]
602 | 
603 |         module_name, obj_name = import_name.rsplit(".", 1)
604 |         module = __import__(module_name, globals(), locals(), [obj_name])
605 |         try:
606 |             return getattr(module, obj_name)
607 |         except AttributeError as e:
608 |             raise ImportError(e) from None
609 | 
610 |     except ImportError as e:
611 |         if not silent:
612 |             raise ImportStringError(import_name, e).with_traceback(
613 |                 sys.exc_info()[2]
614 |             ) from None
615 | 
616 |     return None
617 | 
618 | 
619 | def find_modules(
620 |     import_path: str, include_packages: bool = False, recursive: bool = False
621 | ) -> t.Iterator[str]:
622 |     """Finds all the modules below a package.  This can be useful to
623 |     automatically import all views / controllers so that their metaclasses /
624 |     function decorators have a chance to register themselves on the
625 |     application.
626 | 
627 |     Packages are not returned unless `include_packages` is `True`.  This can
628 |     also recursively list modules but in that case it will import all the
629 |     packages to get the correct load path of that module.
630 | 
631 |     :param import_path: the dotted name for the package to find child modules.
632 |     :param include_packages: set to `True` if packages should be returned, too.
633 |     :param recursive: set to `True` if recursion should happen.
634 |     :return: generator
635 |     """
636 |     module = import_string(import_path)
637 |     path = getattr(module, "__path__", None)
638 |     if path is None:
639 |         raise ValueError(f"{import_path!r} is not a package")
640 |     basename = f"{module.__name__}."
641 |     for _importer, modname, ispkg in pkgutil.iter_modules(path):
642 |         modname = basename + modname
643 |         if ispkg:
644 |             if include_packages:
645 |                 yield modname
646 |             if recursive:
647 |                 yield from find_modules(modname, include_packages, True)
648 |         else:
649 |             yield modname
650 | 
651 | 
652 | class ImportStringError(ImportError):
653 |     """Provides information about a failed :func:`import_string` attempt."""
654 | 
655 |     #: String in dotted notation that failed to be imported.
656 |     import_name: str
657 |     #: Wrapped exception.
658 |     exception: BaseException
659 | 
660 |     def __init__(self, import_name: str, exception: BaseException) -> None:
661 |         self.import_name = import_name
662 |         self.exception = exception
663 |         msg = import_name
664 |         name = ""
665 |         tracked = []
666 |         for part in import_name.replace(":", ".").split("."):
667 |             name = f"{name}.{part}" if name else part
668 |             imported = import_string(name, silent=True)
669 |             if imported:
670 |                 tracked.append((name, getattr(imported, "__file__", None)))
671 |             else:
672 |                 track = [f"- {n!r} found in {i!r}." for n, i in tracked]
673 |                 track.append(f"- {name!r} not found.")
674 |                 track_str = "\n".join(track)
675 |                 msg = (
676 |                     f"import_string() failed for {import_name!r}. Possible reasons"
677 |                     f" are:\n\n"
678 |                     "- missing __init__.py in a package;\n"
679 |                     "- package or module path not included in sys.path;\n"
680 |                     "- duplicated package or module name taking precedence in"
681 |                     " sys.path;\n"
682 |                     "- missing module, class, function or variable;\n\n"
683 |                     f"Debugged import:\n\n{track_str}\n\n"
684 |                     f"Original exception:\n\n{type(exception).__name__}: {exception}"
685 |                 )
686 |                 break
687 | 
688 |         super().__init__(msg)
689 | 
690 |     def __repr__(self) -> str:
691 |         return f"<{type(self).__name__}({self.import_name!r}, {self.exception!r})>"
692 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/metadata/base.py:
--------------------------------------------------------------------------------

```python
  1 | import csv
  2 | import email.message
  3 | import functools
  4 | import json
  5 | import logging
  6 | import pathlib
  7 | import re
  8 | import zipfile
  9 | from typing import (
 10 |     IO,
 11 |     Any,
 12 |     Collection,
 13 |     Container,
 14 |     Dict,
 15 |     Iterable,
 16 |     Iterator,
 17 |     List,
 18 |     NamedTuple,
 19 |     Optional,
 20 |     Protocol,
 21 |     Tuple,
 22 |     Union,
 23 | )
 24 | 
 25 | from pip._vendor.packaging.requirements import Requirement
 26 | from pip._vendor.packaging.specifiers import InvalidSpecifier, SpecifierSet
 27 | from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
 28 | from pip._vendor.packaging.version import Version
 29 | 
 30 | from pip._internal.exceptions import NoneMetadataError
 31 | from pip._internal.locations import site_packages, user_site
 32 | from pip._internal.models.direct_url import (
 33 |     DIRECT_URL_METADATA_NAME,
 34 |     DirectUrl,
 35 |     DirectUrlValidationError,
 36 | )
 37 | from pip._internal.utils.compat import stdlib_pkgs  # TODO: Move definition here.
 38 | from pip._internal.utils.egg_link import egg_link_path_from_sys_path
 39 | from pip._internal.utils.misc import is_local, normalize_path
 40 | from pip._internal.utils.urls import url_to_path
 41 | 
 42 | from ._json import msg_to_json
 43 | 
 44 | InfoPath = Union[str, pathlib.PurePath]
 45 | 
 46 | logger = logging.getLogger(__name__)
 47 | 
 48 | 
 49 | class BaseEntryPoint(Protocol):
 50 |     @property
 51 |     def name(self) -> str:
 52 |         raise NotImplementedError()
 53 | 
 54 |     @property
 55 |     def value(self) -> str:
 56 |         raise NotImplementedError()
 57 | 
 58 |     @property
 59 |     def group(self) -> str:
 60 |         raise NotImplementedError()
 61 | 
 62 | 
 63 | def _convert_installed_files_path(
 64 |     entry: Tuple[str, ...],
 65 |     info: Tuple[str, ...],
 66 | ) -> str:
 67 |     """Convert a legacy installed-files.txt path into modern RECORD path.
 68 | 
 69 |     The legacy format stores paths relative to the info directory, while the
 70 |     modern format stores paths relative to the package root, e.g. the
 71 |     site-packages directory.
 72 | 
 73 |     :param entry: Path parts of the installed-files.txt entry.
 74 |     :param info: Path parts of the egg-info directory relative to package root.
 75 |     :returns: The converted entry.
 76 | 
 77 |     For best compatibility with symlinks, this does not use ``abspath()`` or
 78 |     ``Path.resolve()``, but tries to work with path parts:
 79 | 
 80 |     1. While ``entry`` starts with ``..``, remove the equal amounts of parts
 81 |        from ``info``; if ``info`` is empty, start appending ``..`` instead.
 82 |     2. Join the two directly.
 83 |     """
 84 |     while entry and entry[0] == "..":
 85 |         if not info or info[-1] == "..":
 86 |             info += ("..",)
 87 |         else:
 88 |             info = info[:-1]
 89 |         entry = entry[1:]
 90 |     return str(pathlib.Path(*info, *entry))
 91 | 
 92 | 
 93 | class RequiresEntry(NamedTuple):
 94 |     requirement: str
 95 |     extra: str
 96 |     marker: str
 97 | 
 98 | 
 99 | class BaseDistribution(Protocol):
100 |     @classmethod
101 |     def from_directory(cls, directory: str) -> "BaseDistribution":
102 |         """Load the distribution from a metadata directory.
103 | 
104 |         :param directory: Path to a metadata directory, e.g. ``.dist-info``.
105 |         """
106 |         raise NotImplementedError()
107 | 
108 |     @classmethod
109 |     def from_metadata_file_contents(
110 |         cls,
111 |         metadata_contents: bytes,
112 |         filename: str,
113 |         project_name: str,
114 |     ) -> "BaseDistribution":
115 |         """Load the distribution from the contents of a METADATA file.
116 | 
117 |         This is used to implement PEP 658 by generating a "shallow" dist object that can
118 |         be used for resolution without downloading or building the actual dist yet.
119 | 
120 |         :param metadata_contents: The contents of a METADATA file.
121 |         :param filename: File name for the dist with this metadata.
122 |         :param project_name: Name of the project this dist represents.
123 |         """
124 |         raise NotImplementedError()
125 | 
126 |     @classmethod
127 |     def from_wheel(cls, wheel: "Wheel", name: str) -> "BaseDistribution":
128 |         """Load the distribution from a given wheel.
129 | 
130 |         :param wheel: A concrete wheel definition.
131 |         :param name: File name of the wheel.
132 | 
133 |         :raises InvalidWheel: Whenever loading of the wheel causes a
134 |             :py:exc:`zipfile.BadZipFile` exception to be thrown.
135 |         :raises UnsupportedWheel: If the wheel is a valid zip, but malformed
136 |             internally.
137 |         """
138 |         raise NotImplementedError()
139 | 
140 |     def __repr__(self) -> str:
141 |         return f"{self.raw_name} {self.raw_version} ({self.location})"
142 | 
143 |     def __str__(self) -> str:
144 |         return f"{self.raw_name} {self.raw_version}"
145 | 
146 |     @property
147 |     def location(self) -> Optional[str]:
148 |         """Where the distribution is loaded from.
149 | 
150 |         A string value is not necessarily a filesystem path, since distributions
151 |         can be loaded from other sources, e.g. arbitrary zip archives. ``None``
152 |         means the distribution is created in-memory.
153 | 
154 |         Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If
155 |         this is a symbolic link, we want to preserve the relative path between
156 |         it and files in the distribution.
157 |         """
158 |         raise NotImplementedError()
159 | 
160 |     @property
161 |     def editable_project_location(self) -> Optional[str]:
162 |         """The project location for editable distributions.
163 | 
164 |         This is the directory where pyproject.toml or setup.py is located.
165 |         None if the distribution is not installed in editable mode.
166 |         """
167 |         # TODO: this property is relatively costly to compute, memoize it ?
168 |         direct_url = self.direct_url
169 |         if direct_url:
170 |             if direct_url.is_local_editable():
171 |                 return url_to_path(direct_url.url)
172 |         else:
173 |             # Search for an .egg-link file by walking sys.path, as it was
174 |             # done before by dist_is_editable().
175 |             egg_link_path = egg_link_path_from_sys_path(self.raw_name)
176 |             if egg_link_path:
177 |                 # TODO: get project location from second line of egg_link file
178 |                 #       (https://github.com/pypa/pip/issues/10243)
179 |                 return self.location
180 |         return None
181 | 
182 |     @property
183 |     def installed_location(self) -> Optional[str]:
184 |         """The distribution's "installed" location.
185 | 
186 |         This should generally be a ``site-packages`` directory. This is
187 |         usually ``dist.location``, except for legacy develop-installed packages,
188 |         where ``dist.location`` is the source code location, and this is where
189 |         the ``.egg-link`` file is.
190 | 
191 |         The returned location is normalized (in particular, with symlinks removed).
192 |         """
193 |         raise NotImplementedError()
194 | 
195 |     @property
196 |     def info_location(self) -> Optional[str]:
197 |         """Location of the .[egg|dist]-info directory or file.
198 | 
199 |         Similarly to ``location``, a string value is not necessarily a
200 |         filesystem path. ``None`` means the distribution is created in-memory.
201 | 
202 |         For a modern .dist-info installation on disk, this should be something
203 |         like ``{location}/{raw_name}-{version}.dist-info``.
204 | 
205 |         Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If
206 |         this is a symbolic link, we want to preserve the relative path between
207 |         it and other files in the distribution.
208 |         """
209 |         raise NotImplementedError()
210 | 
211 |     @property
212 |     def installed_by_distutils(self) -> bool:
213 |         """Whether this distribution is installed with legacy distutils format.
214 | 
215 |         A distribution installed with "raw" distutils not patched by setuptools
216 |         uses one single file at ``info_location`` to store metadata. We need to
217 |         treat this specially on uninstallation.
218 |         """
219 |         info_location = self.info_location
220 |         if not info_location:
221 |             return False
222 |         return pathlib.Path(info_location).is_file()
223 | 
224 |     @property
225 |     def installed_as_egg(self) -> bool:
226 |         """Whether this distribution is installed as an egg.
227 | 
228 |         This usually indicates the distribution was installed by (older versions
229 |         of) easy_install.
230 |         """
231 |         location = self.location
232 |         if not location:
233 |             return False
234 |         return location.endswith(".egg")
235 | 
236 |     @property
237 |     def installed_with_setuptools_egg_info(self) -> bool:
238 |         """Whether this distribution is installed with the ``.egg-info`` format.
239 | 
240 |         This usually indicates the distribution was installed with setuptools
241 |         with an old pip version or with ``single-version-externally-managed``.
242 | 
243 |         Note that this ensure the metadata store is a directory. distutils can
244 |         also installs an ``.egg-info``, but as a file, not a directory. This
245 |         property is *False* for that case. Also see ``installed_by_distutils``.
246 |         """
247 |         info_location = self.info_location
248 |         if not info_location:
249 |             return False
250 |         if not info_location.endswith(".egg-info"):
251 |             return False
252 |         return pathlib.Path(info_location).is_dir()
253 | 
254 |     @property
255 |     def installed_with_dist_info(self) -> bool:
256 |         """Whether this distribution is installed with the "modern format".
257 | 
258 |         This indicates a "modern" installation, e.g. storing metadata in the
259 |         ``.dist-info`` directory. This applies to installations made by
260 |         setuptools (but through pip, not directly), or anything using the
261 |         standardized build backend interface (PEP 517).
262 |         """
263 |         info_location = self.info_location
264 |         if not info_location:
265 |             return False
266 |         if not info_location.endswith(".dist-info"):
267 |             return False
268 |         return pathlib.Path(info_location).is_dir()
269 | 
270 |     @property
271 |     def canonical_name(self) -> NormalizedName:
272 |         raise NotImplementedError()
273 | 
274 |     @property
275 |     def version(self) -> Version:
276 |         raise NotImplementedError()
277 | 
278 |     @property
279 |     def raw_version(self) -> str:
280 |         raise NotImplementedError()
281 | 
282 |     @property
283 |     def setuptools_filename(self) -> str:
284 |         """Convert a project name to its setuptools-compatible filename.
285 | 
286 |         This is a copy of ``pkg_resources.to_filename()`` for compatibility.
287 |         """
288 |         return self.raw_name.replace("-", "_")
289 | 
290 |     @property
291 |     def direct_url(self) -> Optional[DirectUrl]:
292 |         """Obtain a DirectUrl from this distribution.
293 | 
294 |         Returns None if the distribution has no `direct_url.json` metadata,
295 |         or if `direct_url.json` is invalid.
296 |         """
297 |         try:
298 |             content = self.read_text(DIRECT_URL_METADATA_NAME)
299 |         except FileNotFoundError:
300 |             return None
301 |         try:
302 |             return DirectUrl.from_json(content)
303 |         except (
304 |             UnicodeDecodeError,
305 |             json.JSONDecodeError,
306 |             DirectUrlValidationError,
307 |         ) as e:
308 |             logger.warning(
309 |                 "Error parsing %s for %s: %s",
310 |                 DIRECT_URL_METADATA_NAME,
311 |                 self.canonical_name,
312 |                 e,
313 |             )
314 |             return None
315 | 
316 |     @property
317 |     def installer(self) -> str:
318 |         try:
319 |             installer_text = self.read_text("INSTALLER")
320 |         except (OSError, ValueError, NoneMetadataError):
321 |             return ""  # Fail silently if the installer file cannot be read.
322 |         for line in installer_text.splitlines():
323 |             cleaned_line = line.strip()
324 |             if cleaned_line:
325 |                 return cleaned_line
326 |         return ""
327 | 
328 |     @property
329 |     def requested(self) -> bool:
330 |         return self.is_file("REQUESTED")
331 | 
332 |     @property
333 |     def editable(self) -> bool:
334 |         return bool(self.editable_project_location)
335 | 
336 |     @property
337 |     def local(self) -> bool:
338 |         """If distribution is installed in the current virtual environment.
339 | 
340 |         Always True if we're not in a virtualenv.
341 |         """
342 |         if self.installed_location is None:
343 |             return False
344 |         return is_local(self.installed_location)
345 | 
346 |     @property
347 |     def in_usersite(self) -> bool:
348 |         if self.installed_location is None or user_site is None:
349 |             return False
350 |         return self.installed_location.startswith(normalize_path(user_site))
351 | 
352 |     @property
353 |     def in_site_packages(self) -> bool:
354 |         if self.installed_location is None or site_packages is None:
355 |             return False
356 |         return self.installed_location.startswith(normalize_path(site_packages))
357 | 
358 |     def is_file(self, path: InfoPath) -> bool:
359 |         """Check whether an entry in the info directory is a file."""
360 |         raise NotImplementedError()
361 | 
362 |     def iter_distutils_script_names(self) -> Iterator[str]:
363 |         """Find distutils 'scripts' entries metadata.
364 | 
365 |         If 'scripts' is supplied in ``setup.py``, distutils records those in the
366 |         installed distribution's ``scripts`` directory, a file for each script.
367 |         """
368 |         raise NotImplementedError()
369 | 
370 |     def read_text(self, path: InfoPath) -> str:
371 |         """Read a file in the info directory.
372 | 
373 |         :raise FileNotFoundError: If ``path`` does not exist in the directory.
374 |         :raise NoneMetadataError: If ``path`` exists in the info directory, but
375 |             cannot be read.
376 |         """
377 |         raise NotImplementedError()
378 | 
379 |     def iter_entry_points(self) -> Iterable[BaseEntryPoint]:
380 |         raise NotImplementedError()
381 | 
382 |     def _metadata_impl(self) -> email.message.Message:
383 |         raise NotImplementedError()
384 | 
385 |     @functools.cached_property
386 |     def metadata(self) -> email.message.Message:
387 |         """Metadata of distribution parsed from e.g. METADATA or PKG-INFO.
388 | 
389 |         This should return an empty message if the metadata file is unavailable.
390 | 
391 |         :raises NoneMetadataError: If the metadata file is available, but does
392 |             not contain valid metadata.
393 |         """
394 |         metadata = self._metadata_impl()
395 |         self._add_egg_info_requires(metadata)
396 |         return metadata
397 | 
398 |     @property
399 |     def metadata_dict(self) -> Dict[str, Any]:
400 |         """PEP 566 compliant JSON-serializable representation of METADATA or PKG-INFO.
401 | 
402 |         This should return an empty dict if the metadata file is unavailable.
403 | 
404 |         :raises NoneMetadataError: If the metadata file is available, but does
405 |             not contain valid metadata.
406 |         """
407 |         return msg_to_json(self.metadata)
408 | 
409 |     @property
410 |     def metadata_version(self) -> Optional[str]:
411 |         """Value of "Metadata-Version:" in distribution metadata, if available."""
412 |         return self.metadata.get("Metadata-Version")
413 | 
414 |     @property
415 |     def raw_name(self) -> str:
416 |         """Value of "Name:" in distribution metadata."""
417 |         # The metadata should NEVER be missing the Name: key, but if it somehow
418 |         # does, fall back to the known canonical name.
419 |         return self.metadata.get("Name", self.canonical_name)
420 | 
421 |     @property
422 |     def requires_python(self) -> SpecifierSet:
423 |         """Value of "Requires-Python:" in distribution metadata.
424 | 
425 |         If the key does not exist or contains an invalid value, an empty
426 |         SpecifierSet should be returned.
427 |         """
428 |         value = self.metadata.get("Requires-Python")
429 |         if value is None:
430 |             return SpecifierSet()
431 |         try:
432 |             # Convert to str to satisfy the type checker; this can be a Header object.
433 |             spec = SpecifierSet(str(value))
434 |         except InvalidSpecifier as e:
435 |             message = "Package %r has an invalid Requires-Python: %s"
436 |             logger.warning(message, self.raw_name, e)
437 |             return SpecifierSet()
438 |         return spec
439 | 
440 |     def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]:
441 |         """Dependencies of this distribution.
442 | 
443 |         For modern .dist-info distributions, this is the collection of
444 |         "Requires-Dist:" entries in distribution metadata.
445 |         """
446 |         raise NotImplementedError()
447 | 
448 |     def iter_raw_dependencies(self) -> Iterable[str]:
449 |         """Raw Requires-Dist metadata."""
450 |         return self.metadata.get_all("Requires-Dist", [])
451 | 
452 |     def iter_provided_extras(self) -> Iterable[NormalizedName]:
453 |         """Extras provided by this distribution.
454 | 
455 |         For modern .dist-info distributions, this is the collection of
456 |         "Provides-Extra:" entries in distribution metadata.
457 | 
458 |         The return value of this function is expected to be normalised names,
459 |         per PEP 685, with the returned value being handled appropriately by
460 |         `iter_dependencies`.
461 |         """
462 |         raise NotImplementedError()
463 | 
464 |     def _iter_declared_entries_from_record(self) -> Optional[Iterator[str]]:
465 |         try:
466 |             text = self.read_text("RECORD")
467 |         except FileNotFoundError:
468 |             return None
469 |         # This extra Path-str cast normalizes entries.
470 |         return (str(pathlib.Path(row[0])) for row in csv.reader(text.splitlines()))
471 | 
472 |     def _iter_declared_entries_from_legacy(self) -> Optional[Iterator[str]]:
473 |         try:
474 |             text = self.read_text("installed-files.txt")
475 |         except FileNotFoundError:
476 |             return None
477 |         paths = (p for p in text.splitlines(keepends=False) if p)
478 |         root = self.location
479 |         info = self.info_location
480 |         if root is None or info is None:
481 |             return paths
482 |         try:
483 |             info_rel = pathlib.Path(info).relative_to(root)
484 |         except ValueError:  # info is not relative to root.
485 |             return paths
486 |         if not info_rel.parts:  # info *is* root.
487 |             return paths
488 |         return (
489 |             _convert_installed_files_path(pathlib.Path(p).parts, info_rel.parts)
490 |             for p in paths
491 |         )
492 | 
493 |     def iter_declared_entries(self) -> Optional[Iterator[str]]:
494 |         """Iterate through file entries declared in this distribution.
495 | 
496 |         For modern .dist-info distributions, this is the files listed in the
497 |         ``RECORD`` metadata file. For legacy setuptools distributions, this
498 |         comes from ``installed-files.txt``, with entries normalized to be
499 |         compatible with the format used by ``RECORD``.
500 | 
501 |         :return: An iterator for listed entries, or None if the distribution
502 |             contains neither ``RECORD`` nor ``installed-files.txt``.
503 |         """
504 |         return (
505 |             self._iter_declared_entries_from_record()
506 |             or self._iter_declared_entries_from_legacy()
507 |         )
508 | 
509 |     def _iter_requires_txt_entries(self) -> Iterator[RequiresEntry]:
510 |         """Parse a ``requires.txt`` in an egg-info directory.
511 | 
512 |         This is an INI-ish format where an egg-info stores dependencies. A
513 |         section name describes extra other environment markers, while each entry
514 |         is an arbitrary string (not a key-value pair) representing a dependency
515 |         as a requirement string (no markers).
516 | 
517 |         There is a construct in ``importlib.metadata`` called ``Sectioned`` that
518 |         does mostly the same, but the format is currently considered private.
519 |         """
520 |         try:
521 |             content = self.read_text("requires.txt")
522 |         except FileNotFoundError:
523 |             return
524 |         extra = marker = ""  # Section-less entries don't have markers.
525 |         for line in content.splitlines():
526 |             line = line.strip()
527 |             if not line or line.startswith("#"):  # Comment; ignored.
528 |                 continue
529 |             if line.startswith("[") and line.endswith("]"):  # A section header.
530 |                 extra, _, marker = line.strip("[]").partition(":")
531 |                 continue
532 |             yield RequiresEntry(requirement=line, extra=extra, marker=marker)
533 | 
534 |     def _iter_egg_info_extras(self) -> Iterable[str]:
535 |         """Get extras from the egg-info directory."""
536 |         known_extras = {""}
537 |         for entry in self._iter_requires_txt_entries():
538 |             extra = canonicalize_name(entry.extra)
539 |             if extra in known_extras:
540 |                 continue
541 |             known_extras.add(extra)
542 |             yield extra
543 | 
544 |     def _iter_egg_info_dependencies(self) -> Iterable[str]:
545 |         """Get distribution dependencies from the egg-info directory.
546 | 
547 |         To ease parsing, this converts a legacy dependency entry into a PEP 508
548 |         requirement string. Like ``_iter_requires_txt_entries()``, there is code
549 |         in ``importlib.metadata`` that does mostly the same, but not do exactly
550 |         what we need.
551 | 
552 |         Namely, ``importlib.metadata`` does not normalize the extra name before
553 |         putting it into the requirement string, which causes marker comparison
554 |         to fail because the dist-info format do normalize. This is consistent in
555 |         all currently available PEP 517 backends, although not standardized.
556 |         """
557 |         for entry in self._iter_requires_txt_entries():
558 |             extra = canonicalize_name(entry.extra)
559 |             if extra and entry.marker:
560 |                 marker = f'({entry.marker}) and extra == "{extra}"'
561 |             elif extra:
562 |                 marker = f'extra == "{extra}"'
563 |             elif entry.marker:
564 |                 marker = entry.marker
565 |             else:
566 |                 marker = ""
567 |             if marker:
568 |                 yield f"{entry.requirement} ; {marker}"
569 |             else:
570 |                 yield entry.requirement
571 | 
572 |     def _add_egg_info_requires(self, metadata: email.message.Message) -> None:
573 |         """Add egg-info requires.txt information to the metadata."""
574 |         if not metadata.get_all("Requires-Dist"):
575 |             for dep in self._iter_egg_info_dependencies():
576 |                 metadata["Requires-Dist"] = dep
577 |         if not metadata.get_all("Provides-Extra"):
578 |             for extra in self._iter_egg_info_extras():
579 |                 metadata["Provides-Extra"] = extra
580 | 
581 | 
582 | class BaseEnvironment:
583 |     """An environment containing distributions to introspect."""
584 | 
585 |     @classmethod
586 |     def default(cls) -> "BaseEnvironment":
587 |         raise NotImplementedError()
588 | 
589 |     @classmethod
590 |     def from_paths(cls, paths: Optional[List[str]]) -> "BaseEnvironment":
591 |         raise NotImplementedError()
592 | 
593 |     def get_distribution(self, name: str) -> Optional["BaseDistribution"]:
594 |         """Given a requirement name, return the installed distributions.
595 | 
596 |         The name may not be normalized. The implementation must canonicalize
597 |         it for lookup.
598 |         """
599 |         raise NotImplementedError()
600 | 
601 |     def _iter_distributions(self) -> Iterator["BaseDistribution"]:
602 |         """Iterate through installed distributions.
603 | 
604 |         This function should be implemented by subclass, but never called
605 |         directly. Use the public ``iter_distribution()`` instead, which
606 |         implements additional logic to make sure the distributions are valid.
607 |         """
608 |         raise NotImplementedError()
609 | 
610 |     def iter_all_distributions(self) -> Iterator[BaseDistribution]:
611 |         """Iterate through all installed distributions without any filtering."""
612 |         for dist in self._iter_distributions():
613 |             # Make sure the distribution actually comes from a valid Python
614 |             # packaging distribution. Pip's AdjacentTempDirectory leaves folders
615 |             # e.g. ``~atplotlib.dist-info`` if cleanup was interrupted. The
616 |             # valid project name pattern is taken from PEP 508.
617 |             project_name_valid = re.match(
618 |                 r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$",
619 |                 dist.canonical_name,
620 |                 flags=re.IGNORECASE,
621 |             )
622 |             if not project_name_valid:
623 |                 logger.warning(
624 |                     "Ignoring invalid distribution %s (%s)",
625 |                     dist.canonical_name,
626 |                     dist.location,
627 |                 )
628 |                 continue
629 |             yield dist
630 | 
631 |     def iter_installed_distributions(
632 |         self,
633 |         local_only: bool = True,
634 |         skip: Container[str] = stdlib_pkgs,
635 |         include_editables: bool = True,
636 |         editables_only: bool = False,
637 |         user_only: bool = False,
638 |     ) -> Iterator[BaseDistribution]:
639 |         """Return a list of installed distributions.
640 | 
641 |         This is based on ``iter_all_distributions()`` with additional filtering
642 |         options. Note that ``iter_installed_distributions()`` without arguments
643 |         is *not* equal to ``iter_all_distributions()``, since some of the
644 |         configurations exclude packages by default.
645 | 
646 |         :param local_only: If True (default), only return installations
647 |         local to the current virtualenv, if in a virtualenv.
648 |         :param skip: An iterable of canonicalized project names to ignore;
649 |             defaults to ``stdlib_pkgs``.
650 |         :param include_editables: If False, don't report editables.
651 |         :param editables_only: If True, only report editables.
652 |         :param user_only: If True, only report installations in the user
653 |         site directory.
654 |         """
655 |         it = self.iter_all_distributions()
656 |         if local_only:
657 |             it = (d for d in it if d.local)
658 |         if not include_editables:
659 |             it = (d for d in it if not d.editable)
660 |         if editables_only:
661 |             it = (d for d in it if d.editable)
662 |         if user_only:
663 |             it = (d for d in it if d.in_usersite)
664 |         return (d for d in it if d.canonical_name not in skip)
665 | 
666 | 
667 | class Wheel(Protocol):
668 |     location: str
669 | 
670 |     def as_zipfile(self) -> zipfile.ZipFile:
671 |         raise NotImplementedError()
672 | 
673 | 
674 | class FilesystemWheel(Wheel):
675 |     def __init__(self, location: str) -> None:
676 |         self.location = location
677 | 
678 |     def as_zipfile(self) -> zipfile.ZipFile:
679 |         return zipfile.ZipFile(self.location, allowZip64=True)
680 | 
681 | 
682 | class MemoryWheel(Wheel):
683 |     def __init__(self, location: str, stream: IO[bytes]) -> None:
684 |         self.location = location
685 |         self.stream = stream
686 | 
687 |     def as_zipfile(self) -> zipfile.ZipFile:
688 |         return zipfile.ZipFile(self.stream, allowZip64=True)
689 | 
```
Page 84/168FirstPrevNextLast