This is page 17 of 168. Use http://codebase.md/romanshablio/mcp_server?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .DS_Store
├── .venv
│ ├── __pycache__
│ │ └── hello.cpython-312.pyc
│ ├── bin
│ │ ├── activate
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── Activate.ps1
│ │ ├── flask
│ │ ├── normalizer
│ │ ├── pip
│ │ ├── pip3
│ │ ├── pip3.12
│ │ ├── python
│ │ ├── python3
│ │ └── python3.12
│ ├── hello.py
│ ├── lib
│ │ └── python3.12
│ │ └── site-packages
│ │ ├── beautifulsoup4-4.12.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ ├── AUTHORS
│ │ │ │ └── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── blinker
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _utilities.cpython-312.pyc
│ │ │ │ └── base.cpython-312.pyc
│ │ │ ├── _utilities.py
│ │ │ ├── base.py
│ │ │ └── py.typed
│ │ ├── blinker-1.8.2.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── bs4
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── css.cpython-312.pyc
│ │ │ │ ├── dammit.cpython-312.pyc
│ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ ├── element.cpython-312.pyc
│ │ │ │ └── formatter.cpython-312.pyc
│ │ │ ├── builder
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _html5lib.cpython-312.pyc
│ │ │ │ │ ├── _htmlparser.cpython-312.pyc
│ │ │ │ │ └── _lxml.cpython-312.pyc
│ │ │ │ ├── _html5lib.py
│ │ │ │ ├── _htmlparser.py
│ │ │ │ └── _lxml.py
│ │ │ ├── css.py
│ │ │ ├── dammit.py
│ │ │ ├── diagnose.py
│ │ │ ├── element.py
│ │ │ ├── formatter.py
│ │ │ └── tests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── test_builder_registry.cpython-312.pyc
│ │ │ │ ├── test_builder.cpython-312.pyc
│ │ │ │ ├── test_css.cpython-312.pyc
│ │ │ │ ├── test_dammit.cpython-312.pyc
│ │ │ │ ├── test_docs.cpython-312.pyc
│ │ │ │ ├── test_element.cpython-312.pyc
│ │ │ │ ├── test_formatter.cpython-312.pyc
│ │ │ │ ├── test_fuzz.cpython-312.pyc
│ │ │ │ ├── test_html5lib.cpython-312.pyc
│ │ │ │ ├── test_htmlparser.cpython-312.pyc
│ │ │ │ ├── test_lxml.cpython-312.pyc
│ │ │ │ ├── test_navigablestring.cpython-312.pyc
│ │ │ │ ├── test_pageelement.cpython-312.pyc
│ │ │ │ ├── test_soup.cpython-312.pyc
│ │ │ │ ├── test_tag.cpython-312.pyc
│ │ │ │ └── test_tree.cpython-312.pyc
│ │ │ ├── fuzz
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase
│ │ │ │ ├── crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase
│ │ │ │ └── crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase
│ │ │ ├── test_builder_registry.py
│ │ │ ├── test_builder.py
│ │ │ ├── test_css.py
│ │ │ ├── test_dammit.py
│ │ │ ├── test_docs.py
│ │ │ ├── test_element.py
│ │ │ ├── test_formatter.py
│ │ │ ├── test_fuzz.py
│ │ │ ├── test_html5lib.py
│ │ │ ├── test_htmlparser.py
│ │ │ ├── test_lxml.py
│ │ │ ├── test_navigablestring.py
│ │ │ ├── test_pageelement.py
│ │ │ ├── test_soup.py
│ │ │ ├── test_tag.py
│ │ │ └── test_tree.py
│ │ ├── certifi
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── core.cpython-312.pyc
│ │ │ ├── cacert.pem
│ │ │ ├── core.py
│ │ │ └── py.typed
│ │ ├── certifi-2024.8.30.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── charset_normalizer
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── cd.cpython-312.pyc
│ │ │ │ ├── constant.cpython-312.pyc
│ │ │ │ ├── legacy.cpython-312.pyc
│ │ │ │ ├── md.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── version.cpython-312.pyc
│ │ │ ├── api.py
│ │ │ ├── cd.py
│ │ │ ├── cli
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── __main__.cpython-312.pyc
│ │ │ ├── constant.py
│ │ │ ├── legacy.py
│ │ │ ├── md__mypyc.cpython-312-darwin.so
│ │ │ ├── md.cpython-312-darwin.so
│ │ │ ├── md.py
│ │ │ ├── models.py
│ │ │ ├── py.typed
│ │ │ ├── utils.py
│ │ │ └── version.py
│ │ ├── charset_normalizer-3.4.0.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── click
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ ├── _termui_impl.cpython-312.pyc
│ │ │ │ ├── _textwrap.cpython-312.pyc
│ │ │ │ ├── _winconsole.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── decorators.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formatting.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── shell_completion.cpython-312.pyc
│ │ │ │ ├── termui.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── types.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── _compat.py
│ │ │ ├── _termui_impl.py
│ │ │ ├── _textwrap.py
│ │ │ ├── _winconsole.py
│ │ │ ├── core.py
│ │ │ ├── decorators.py
│ │ │ ├── exceptions.py
│ │ │ ├── formatting.py
│ │ │ ├── globals.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── shell_completion.py
│ │ │ ├── termui.py
│ │ │ ├── testing.py
│ │ │ ├── types.py
│ │ │ └── utils.py
│ │ ├── click-8.1.7.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.rst
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── fake_useragent
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ ├── fake.cpython-312.pyc
│ │ │ │ ├── log.cpython-312.pyc
│ │ │ │ ├── settings.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── data
│ │ │ │ └── browsers.json
│ │ │ ├── errors.py
│ │ │ ├── fake.py
│ │ │ ├── log.py
│ │ │ ├── settings.py
│ │ │ └── utils.py
│ │ ├── fake_useragent-1.5.1.dist-info
│ │ │ ├── AUTHORS
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── flask
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ ├── cli.cpython-312.pyc
│ │ │ │ ├── config.cpython-312.pyc
│ │ │ │ ├── ctx.cpython-312.pyc
│ │ │ │ ├── debughelpers.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── helpers.cpython-312.pyc
│ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── signals.cpython-312.pyc
│ │ │ │ ├── templating.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── typing.cpython-312.pyc
│ │ │ │ ├── views.cpython-312.pyc
│ │ │ │ └── wrappers.cpython-312.pyc
│ │ │ ├── app.py
│ │ │ ├── blueprints.py
│ │ │ ├── cli.py
│ │ │ ├── config.py
│ │ │ ├── ctx.py
│ │ │ ├── debughelpers.py
│ │ │ ├── globals.py
│ │ │ ├── helpers.py
│ │ │ ├── json
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ └── tag.cpython-312.pyc
│ │ │ │ ├── provider.py
│ │ │ │ └── tag.py
│ │ │ ├── logging.py
│ │ │ ├── py.typed
│ │ │ ├── sansio
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ │ └── scaffold.cpython-312.pyc
│ │ │ │ ├── app.py
│ │ │ │ ├── blueprints.py
│ │ │ │ ├── README.md
│ │ │ │ └── scaffold.py
│ │ │ ├── sessions.py
│ │ │ ├── signals.py
│ │ │ ├── templating.py
│ │ │ ├── testing.py
│ │ │ ├── typing.py
│ │ │ ├── views.py
│ │ │ └── wrappers.py
│ │ ├── flask-3.0.3.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── idna
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ ├── codec.py
│ │ │ ├── compat.py
│ │ │ ├── core.py
│ │ │ ├── idnadata.py
│ │ │ ├── intranges.py
│ │ │ ├── package_data.py
│ │ │ ├── py.typed
│ │ │ └── uts46data.py
│ │ ├── idna-3.10.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── itsdangerous
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ ├── exc.cpython-312.pyc
│ │ │ │ ├── serializer.cpython-312.pyc
│ │ │ │ ├── signer.cpython-312.pyc
│ │ │ │ ├── timed.cpython-312.pyc
│ │ │ │ └── url_safe.cpython-312.pyc
│ │ │ ├── _json.py
│ │ │ ├── encoding.py
│ │ │ ├── exc.py
│ │ │ ├── py.typed
│ │ │ ├── serializer.py
│ │ │ ├── signer.py
│ │ │ ├── timed.py
│ │ │ └── url_safe.py
│ │ ├── itsdangerous-2.2.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── jinja2
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _identifier.cpython-312.pyc
│ │ │ │ ├── async_utils.cpython-312.pyc
│ │ │ │ ├── bccache.cpython-312.pyc
│ │ │ │ ├── compiler.cpython-312.pyc
│ │ │ │ ├── constants.cpython-312.pyc
│ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ ├── defaults.cpython-312.pyc
│ │ │ │ ├── environment.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ ├── filters.cpython-312.pyc
│ │ │ │ ├── idtracking.cpython-312.pyc
│ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ ├── loaders.cpython-312.pyc
│ │ │ │ ├── meta.cpython-312.pyc
│ │ │ │ ├── nativetypes.cpython-312.pyc
│ │ │ │ ├── nodes.cpython-312.pyc
│ │ │ │ ├── optimizer.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── runtime.cpython-312.pyc
│ │ │ │ ├── sandbox.cpython-312.pyc
│ │ │ │ ├── tests.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── visitor.cpython-312.pyc
│ │ │ ├── _identifier.py
│ │ │ ├── async_utils.py
│ │ │ ├── bccache.py
│ │ │ ├── compiler.py
│ │ │ ├── constants.py
│ │ │ ├── debug.py
│ │ │ ├── defaults.py
│ │ │ ├── environment.py
│ │ │ ├── exceptions.py
│ │ │ ├── ext.py
│ │ │ ├── filters.py
│ │ │ ├── idtracking.py
│ │ │ ├── lexer.py
│ │ │ ├── loaders.py
│ │ │ ├── meta.py
│ │ │ ├── nativetypes.py
│ │ │ ├── nodes.py
│ │ │ ├── optimizer.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── runtime.py
│ │ │ ├── sandbox.py
│ │ │ ├── tests.py
│ │ │ ├── utils.py
│ │ │ └── visitor.py
│ │ ├── jinja2-3.1.4.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── lxml
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _elementpath.cpython-312.pyc
│ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ ├── cssselect.cpython-312.pyc
│ │ │ │ ├── doctestcompare.cpython-312.pyc
│ │ │ │ ├── ElementInclude.cpython-312.pyc
│ │ │ │ ├── pyclasslookup.cpython-312.pyc
│ │ │ │ ├── sax.cpython-312.pyc
│ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ ├── _elementpath.cpython-312-darwin.so
│ │ │ ├── _elementpath.py
│ │ │ ├── apihelpers.pxi
│ │ │ ├── builder.cpython-312-darwin.so
│ │ │ ├── builder.py
│ │ │ ├── classlookup.pxi
│ │ │ ├── cleanup.pxi
│ │ │ ├── cssselect.py
│ │ │ ├── debug.pxi
│ │ │ ├── docloader.pxi
│ │ │ ├── doctestcompare.py
│ │ │ ├── dtd.pxi
│ │ │ ├── ElementInclude.py
│ │ │ ├── etree_api.h
│ │ │ ├── etree.cpython-312-darwin.so
│ │ │ ├── etree.h
│ │ │ ├── etree.pyx
│ │ │ ├── extensions.pxi
│ │ │ ├── html
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _diffcommand.cpython-312.pyc
│ │ │ │ │ ├── _html5builder.cpython-312.pyc
│ │ │ │ │ ├── _setmixin.cpython-312.pyc
│ │ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ │ ├── clean.cpython-312.pyc
│ │ │ │ │ ├── defs.cpython-312.pyc
│ │ │ │ │ ├── diff.cpython-312.pyc
│ │ │ │ │ ├── ElementSoup.cpython-312.pyc
│ │ │ │ │ ├── formfill.cpython-312.pyc
│ │ │ │ │ ├── html5parser.cpython-312.pyc
│ │ │ │ │ ├── soupparser.cpython-312.pyc
│ │ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ │ ├── _diffcommand.py
│ │ │ │ ├── _html5builder.py
│ │ │ │ ├── _setmixin.py
│ │ │ │ ├── builder.py
│ │ │ │ ├── clean.py
│ │ │ │ ├── defs.py
│ │ │ │ ├── diff.cpython-312-darwin.so
│ │ │ │ ├── diff.py
│ │ │ │ ├── ElementSoup.py
│ │ │ │ ├── formfill.py
│ │ │ │ ├── html5parser.py
│ │ │ │ ├── soupparser.py
│ │ │ │ └── usedoctest.py
│ │ │ ├── includes
│ │ │ │ ├── __init__.pxd
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── c14n.pxd
│ │ │ │ ├── config.pxd
│ │ │ │ ├── dtdvalid.pxd
│ │ │ │ ├── etree_defs.h
│ │ │ │ ├── etreepublic.pxd
│ │ │ │ ├── extlibs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── libcharset.h
│ │ │ │ │ ├── localcharset.h
│ │ │ │ │ ├── zconf.h
│ │ │ │ │ └── zlib.h
│ │ │ │ ├── htmlparser.pxd
│ │ │ │ ├── libexslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── exslt.h
│ │ │ │ │ ├── exsltconfig.h
│ │ │ │ │ └── exsltexports.h
│ │ │ │ ├── libxml
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── c14n.h
│ │ │ │ │ ├── catalog.h
│ │ │ │ │ ├── chvalid.h
│ │ │ │ │ ├── debugXML.h
│ │ │ │ │ ├── dict.h
│ │ │ │ │ ├── encoding.h
│ │ │ │ │ ├── entities.h
│ │ │ │ │ ├── globals.h
│ │ │ │ │ ├── hash.h
│ │ │ │ │ ├── HTMLparser.h
│ │ │ │ │ ├── HTMLtree.h
│ │ │ │ │ ├── list.h
│ │ │ │ │ ├── nanoftp.h
│ │ │ │ │ ├── nanohttp.h
│ │ │ │ │ ├── parser.h
│ │ │ │ │ ├── parserInternals.h
│ │ │ │ │ ├── relaxng.h
│ │ │ │ │ ├── SAX.h
│ │ │ │ │ ├── SAX2.h
│ │ │ │ │ ├── schemasInternals.h
│ │ │ │ │ ├── schematron.h
│ │ │ │ │ ├── threads.h
│ │ │ │ │ ├── tree.h
│ │ │ │ │ ├── uri.h
│ │ │ │ │ ├── valid.h
│ │ │ │ │ ├── xinclude.h
│ │ │ │ │ ├── xlink.h
│ │ │ │ │ ├── xmlautomata.h
│ │ │ │ │ ├── xmlerror.h
│ │ │ │ │ ├── xmlexports.h
│ │ │ │ │ ├── xmlIO.h
│ │ │ │ │ ├── xmlmemory.h
│ │ │ │ │ ├── xmlmodule.h
│ │ │ │ │ ├── xmlreader.h
│ │ │ │ │ ├── xmlregexp.h
│ │ │ │ │ ├── xmlsave.h
│ │ │ │ │ ├── xmlschemas.h
│ │ │ │ │ ├── xmlschemastypes.h
│ │ │ │ │ ├── xmlstring.h
│ │ │ │ │ ├── xmlunicode.h
│ │ │ │ │ ├── xmlversion.h
│ │ │ │ │ ├── xmlwriter.h
│ │ │ │ │ ├── xpath.h
│ │ │ │ │ ├── xpathInternals.h
│ │ │ │ │ └── xpointer.h
│ │ │ │ ├── libxslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── attributes.h
│ │ │ │ │ ├── documents.h
│ │ │ │ │ ├── extensions.h
│ │ │ │ │ ├── extra.h
│ │ │ │ │ ├── functions.h
│ │ │ │ │ ├── imports.h
│ │ │ │ │ ├── keys.h
│ │ │ │ │ ├── namespaces.h
│ │ │ │ │ ├── numbersInternals.h
│ │ │ │ │ ├── pattern.h
│ │ │ │ │ ├── preproc.h
│ │ │ │ │ ├── security.h
│ │ │ │ │ ├── templates.h
│ │ │ │ │ ├── transform.h
│ │ │ │ │ ├── variables.h
│ │ │ │ │ ├── xslt.h
│ │ │ │ │ ├── xsltconfig.h
│ │ │ │ │ ├── xsltexports.h
│ │ │ │ │ ├── xsltInternals.h
│ │ │ │ │ ├── xsltlocale.h
│ │ │ │ │ └── xsltutils.h
│ │ │ │ ├── lxml-version.h
│ │ │ │ ├── relaxng.pxd
│ │ │ │ ├── schematron.pxd
│ │ │ │ ├── tree.pxd
│ │ │ │ ├── uri.pxd
│ │ │ │ ├── xinclude.pxd
│ │ │ │ ├── xmlerror.pxd
│ │ │ │ ├── xmlparser.pxd
│ │ │ │ ├── xmlschema.pxd
│ │ │ │ ├── xpath.pxd
│ │ │ │ └── xslt.pxd
│ │ │ ├── isoschematron
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ └── resources
│ │ │ │ ├── rng
│ │ │ │ │ └── iso-schematron.rng
│ │ │ │ └── xsl
│ │ │ │ ├── iso-schematron-xslt1
│ │ │ │ │ ├── iso_abstract_expand.xsl
│ │ │ │ │ ├── iso_dsdl_include.xsl
│ │ │ │ │ ├── iso_schematron_message.xsl
│ │ │ │ │ ├── iso_schematron_skeleton_for_xslt1.xsl
│ │ │ │ │ ├── iso_svrl_for_xslt1.xsl
│ │ │ │ │ └── readme.txt
│ │ │ │ ├── RNG2Schtrn.xsl
│ │ │ │ └── XSD2Schtrn.xsl
│ │ │ ├── iterparse.pxi
│ │ │ ├── lxml.etree_api.h
│ │ │ ├── lxml.etree.h
│ │ │ ├── nsclasses.pxi
│ │ │ ├── objectify.cpython-312-darwin.so
│ │ │ ├── objectify.pyx
│ │ │ ├── objectpath.pxi
│ │ │ ├── parser.pxi
│ │ │ ├── parsertarget.pxi
│ │ │ ├── proxy.pxi
│ │ │ ├── public-api.pxi
│ │ │ ├── pyclasslookup.py
│ │ │ ├── readonlytree.pxi
│ │ │ ├── relaxng.pxi
│ │ │ ├── sax.cpython-312-darwin.so
│ │ │ ├── sax.py
│ │ │ ├── saxparser.pxi
│ │ │ ├── schematron.pxi
│ │ │ ├── serializer.pxi
│ │ │ ├── usedoctest.py
│ │ │ ├── xinclude.pxi
│ │ │ ├── xmlerror.pxi
│ │ │ ├── xmlid.pxi
│ │ │ ├── xmlschema.pxi
│ │ │ ├── xpath.pxi
│ │ │ ├── xslt.pxi
│ │ │ └── xsltext.pxi
│ │ ├── lxml-5.3.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── LICENSES.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── markupsafe
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── _native.cpython-312.pyc
│ │ │ ├── _native.py
│ │ │ ├── _speedups.c
│ │ │ ├── _speedups.cpython-312-darwin.so
│ │ │ ├── _speedups.pyi
│ │ │ └── py.typed
│ │ ├── MarkupSafe-3.0.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── pip
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pip-runner__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── __pip-runner__.cpython-312.pyc
│ │ │ ├── _internal
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── build_env.cpython-312.pyc
│ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ ├── pyproject.cpython-312.pyc
│ │ │ │ │ ├── self_outdated_check.cpython-312.pyc
│ │ │ │ │ └── wheel_builder.cpython-312.pyc
│ │ │ │ ├── build_env.py
│ │ │ │ ├── cache.py
│ │ │ │ ├── cli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── autocompletion.cpython-312.pyc
│ │ │ │ │ │ ├── base_command.cpython-312.pyc
│ │ │ │ │ │ ├── cmdoptions.cpython-312.pyc
│ │ │ │ │ │ ├── command_context.cpython-312.pyc
│ │ │ │ │ │ ├── index_command.cpython-312.pyc
│ │ │ │ │ │ ├── main_parser.cpython-312.pyc
│ │ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bars.cpython-312.pyc
│ │ │ │ │ │ ├── req_command.cpython-312.pyc
│ │ │ │ │ │ ├── spinners.cpython-312.pyc
│ │ │ │ │ │ └── status_codes.cpython-312.pyc
│ │ │ │ │ ├── autocompletion.py
│ │ │ │ │ ├── base_command.py
│ │ │ │ │ ├── cmdoptions.py
│ │ │ │ │ ├── command_context.py
│ │ │ │ │ ├── index_command.py
│ │ │ │ │ ├── main_parser.py
│ │ │ │ │ ├── main.py
│ │ │ │ │ ├── parser.py
│ │ │ │ │ ├── progress_bars.py
│ │ │ │ │ ├── req_command.py
│ │ │ │ │ ├── spinners.py
│ │ │ │ │ └── status_codes.py
│ │ │ │ ├── commands
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── completion.cpython-312.pyc
│ │ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ ├── hash.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── inspect.cpython-312.pyc
│ │ │ │ │ │ ├── install.cpython-312.pyc
│ │ │ │ │ │ ├── list.cpython-312.pyc
│ │ │ │ │ │ ├── search.cpython-312.pyc
│ │ │ │ │ │ ├── show.cpython-312.pyc
│ │ │ │ │ │ ├── uninstall.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── completion.py
│ │ │ │ │ ├── configuration.py
│ │ │ │ │ ├── debug.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── hash.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── inspect.py
│ │ │ │ │ ├── install.py
│ │ │ │ │ ├── list.py
│ │ │ │ │ ├── search.py
│ │ │ │ │ ├── show.py
│ │ │ │ │ ├── uninstall.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── configuration.py
│ │ │ │ ├── distributions
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── installed.cpython-312.pyc
│ │ │ │ │ │ ├── sdist.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── installed.py
│ │ │ │ │ ├── sdist.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── index
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── collector.cpython-312.pyc
│ │ │ │ │ │ ├── package_finder.cpython-312.pyc
│ │ │ │ │ │ └── sources.cpython-312.pyc
│ │ │ │ │ ├── collector.py
│ │ │ │ │ ├── package_finder.py
│ │ │ │ │ └── sources.py
│ │ │ │ ├── locations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _distutils.cpython-312.pyc
│ │ │ │ │ │ ├── _sysconfig.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── _distutils.py
│ │ │ │ │ ├── _sysconfig.py
│ │ │ │ │ └── base.py
│ │ │ │ ├── main.py
│ │ │ │ ├── metadata
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ └── pkg_resources.cpython-312.pyc
│ │ │ │ │ ├── _json.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── importlib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ │ ├── _dists.cpython-312.pyc
│ │ │ │ │ │ │ └── _envs.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.py
│ │ │ │ │ │ ├── _dists.py
│ │ │ │ │ │ └── _envs.py
│ │ │ │ │ └── pkg_resources.py
│ │ │ │ ├── models
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── candidate.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url.cpython-312.pyc
│ │ │ │ │ │ ├── format_control.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── installation_report.cpython-312.pyc
│ │ │ │ │ │ ├── link.cpython-312.pyc
│ │ │ │ │ │ ├── scheme.cpython-312.pyc
│ │ │ │ │ │ ├── search_scope.cpython-312.pyc
│ │ │ │ │ │ ├── selection_prefs.cpython-312.pyc
│ │ │ │ │ │ ├── target_python.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── candidate.py
│ │ │ │ │ ├── direct_url.py
│ │ │ │ │ ├── format_control.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── installation_report.py
│ │ │ │ │ ├── link.py
│ │ │ │ │ ├── scheme.py
│ │ │ │ │ ├── search_scope.py
│ │ │ │ │ ├── selection_prefs.py
│ │ │ │ │ ├── target_python.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── network
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── lazy_wheel.cpython-312.pyc
│ │ │ │ │ │ ├── session.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── xmlrpc.cpython-312.pyc
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── lazy_wheel.py
│ │ │ │ │ ├── session.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── xmlrpc.py
│ │ │ │ ├── operations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ └── prepare.cpython-312.pyc
│ │ │ │ │ ├── build
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── build_tracker.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_legacy.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── build_tracker.py
│ │ │ │ │ │ ├── metadata_editable.py
│ │ │ │ │ │ ├── metadata_legacy.py
│ │ │ │ │ │ ├── metadata.py
│ │ │ │ │ │ ├── wheel_editable.py
│ │ │ │ │ │ ├── wheel_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── install
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── editable_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── editable_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ └── prepare.py
│ │ │ │ ├── pyproject.py
│ │ │ │ ├── req
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── constructors.cpython-312.pyc
│ │ │ │ │ │ ├── req_file.cpython-312.pyc
│ │ │ │ │ │ ├── req_install.cpython-312.pyc
│ │ │ │ │ │ ├── req_set.cpython-312.pyc
│ │ │ │ │ │ └── req_uninstall.cpython-312.pyc
│ │ │ │ │ ├── constructors.py
│ │ │ │ │ ├── req_file.py
│ │ │ │ │ ├── req_install.py
│ │ │ │ │ ├── req_set.py
│ │ │ │ │ └── req_uninstall.py
│ │ │ │ ├── resolution
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── legacy
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ │ └── resolver.py
│ │ │ │ │ └── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── candidates.cpython-312.pyc
│ │ │ │ │ │ ├── factory.cpython-312.pyc
│ │ │ │ │ │ ├── found_candidates.cpython-312.pyc
│ │ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ │ ├── reporter.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── candidates.py
│ │ │ │ │ ├── factory.py
│ │ │ │ │ ├── found_candidates.py
│ │ │ │ │ ├── provider.py
│ │ │ │ │ ├── reporter.py
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ └── resolver.py
│ │ │ │ ├── self_outdated_check.py
│ │ │ │ ├── utils
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _jaraco_text.cpython-312.pyc
│ │ │ │ │ │ ├── _log.cpython-312.pyc
│ │ │ │ │ │ ├── appdirs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── compatibility_tags.cpython-312.pyc
│ │ │ │ │ │ ├── datetime.cpython-312.pyc
│ │ │ │ │ │ ├── deprecation.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url_helpers.cpython-312.pyc
│ │ │ │ │ │ ├── egg_link.cpython-312.pyc
│ │ │ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ │ │ ├── entrypoints.cpython-312.pyc
│ │ │ │ │ │ ├── filesystem.cpython-312.pyc
│ │ │ │ │ │ ├── filetypes.cpython-312.pyc
│ │ │ │ │ │ ├── glibc.cpython-312.pyc
│ │ │ │ │ │ ├── hashes.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── misc.cpython-312.pyc
│ │ │ │ │ │ ├── packaging.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── setuptools_build.cpython-312.pyc
│ │ │ │ │ │ ├── subprocess.cpython-312.pyc
│ │ │ │ │ │ ├── temp_dir.cpython-312.pyc
│ │ │ │ │ │ ├── unpacking.cpython-312.pyc
│ │ │ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ │ │ ├── virtualenv.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── _jaraco_text.py
│ │ │ │ │ ├── _log.py
│ │ │ │ │ ├── appdirs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── compatibility_tags.py
│ │ │ │ │ ├── datetime.py
│ │ │ │ │ ├── deprecation.py
│ │ │ │ │ ├── direct_url_helpers.py
│ │ │ │ │ ├── egg_link.py
│ │ │ │ │ ├── encoding.py
│ │ │ │ │ ├── entrypoints.py
│ │ │ │ │ ├── filesystem.py
│ │ │ │ │ ├── filetypes.py
│ │ │ │ │ ├── glibc.py
│ │ │ │ │ ├── hashes.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── misc.py
│ │ │ │ │ ├── packaging.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── setuptools_build.py
│ │ │ │ │ ├── subprocess.py
│ │ │ │ │ ├── temp_dir.py
│ │ │ │ │ ├── unpacking.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ ├── virtualenv.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── vcs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── bazaar.cpython-312.pyc
│ │ │ │ │ │ ├── git.cpython-312.pyc
│ │ │ │ │ │ ├── mercurial.cpython-312.pyc
│ │ │ │ │ │ ├── subversion.cpython-312.pyc
│ │ │ │ │ │ └── versioncontrol.cpython-312.pyc
│ │ │ │ │ ├── bazaar.py
│ │ │ │ │ ├── git.py
│ │ │ │ │ ├── mercurial.py
│ │ │ │ │ ├── subversion.py
│ │ │ │ │ └── versioncontrol.py
│ │ │ │ └── wheel_builder.py
│ │ │ ├── _vendor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ └── typing_extensions.cpython-312.pyc
│ │ │ │ ├── cachecontrol
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _cmd.cpython-312.pyc
│ │ │ │ │ │ ├── adapter.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── controller.cpython-312.pyc
│ │ │ │ │ │ ├── filewrapper.cpython-312.pyc
│ │ │ │ │ │ ├── heuristics.cpython-312.pyc
│ │ │ │ │ │ ├── serialize.cpython-312.pyc
│ │ │ │ │ │ └── wrapper.cpython-312.pyc
│ │ │ │ │ ├── _cmd.py
│ │ │ │ │ ├── adapter.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── caches
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── file_cache.cpython-312.pyc
│ │ │ │ │ │ │ └── redis_cache.cpython-312.pyc
│ │ │ │ │ │ ├── file_cache.py
│ │ │ │ │ │ └── redis_cache.py
│ │ │ │ │ ├── controller.py
│ │ │ │ │ ├── filewrapper.py
│ │ │ │ │ ├── heuristics.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── serialize.py
│ │ │ │ │ └── wrapper.py
│ │ │ │ ├── certifi
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── core.cpython-312.pyc
│ │ │ │ │ ├── cacert.pem
│ │ │ │ │ ├── core.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── distlib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── database.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── locators.cpython-312.pyc
│ │ │ │ │ │ ├── manifest.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── resources.cpython-312.pyc
│ │ │ │ │ │ ├── scripts.cpython-312.pyc
│ │ │ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── database.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── locators.py
│ │ │ │ │ ├── manifest.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── resources.py
│ │ │ │ │ ├── scripts.py
│ │ │ │ │ ├── t32.exe
│ │ │ │ │ ├── t64-arm.exe
│ │ │ │ │ ├── t64.exe
│ │ │ │ │ ├── util.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ ├── w32.exe
│ │ │ │ │ ├── w64-arm.exe
│ │ │ │ │ ├── w64.exe
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── distro
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── distro.cpython-312.pyc
│ │ │ │ │ ├── distro.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── idna
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ │ │ ├── codec.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── core.py
│ │ │ │ │ ├── idnadata.py
│ │ │ │ │ ├── intranges.py
│ │ │ │ │ ├── package_data.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ └── uts46data.py
│ │ │ │ ├── msgpack
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ │ │ └── fallback.cpython-312.pyc
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── ext.py
│ │ │ │ │ └── fallback.py
│ │ │ │ ├── packaging
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _elffile.cpython-312.pyc
│ │ │ │ │ │ ├── _manylinux.cpython-312.pyc
│ │ │ │ │ │ ├── _musllinux.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _structures.cpython-312.pyc
│ │ │ │ │ │ ├── _tokenizer.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ ├── specifiers.cpython-312.pyc
│ │ │ │ │ │ ├── tags.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── version.cpython-312.pyc
│ │ │ │ │ ├── _elffile.py
│ │ │ │ │ ├── _manylinux.py
│ │ │ │ │ ├── _musllinux.py
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _structures.py
│ │ │ │ │ ├── _tokenizer.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ ├── specifiers.py
│ │ │ │ │ ├── tags.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── version.py
│ │ │ │ ├── pkg_resources
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── platformdirs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── android.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── macos.cpython-312.pyc
│ │ │ │ │ │ ├── unix.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── windows.cpython-312.pyc
│ │ │ │ │ ├── android.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── macos.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── unix.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ └── windows.py
│ │ │ │ ├── pygments
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── cmdline.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── filter.cpython-312.pyc
│ │ │ │ │ │ ├── formatter.cpython-312.pyc
│ │ │ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ │ │ ├── modeline.cpython-312.pyc
│ │ │ │ │ │ ├── plugin.cpython-312.pyc
│ │ │ │ │ │ ├── regexopt.cpython-312.pyc
│ │ │ │ │ │ ├── scanner.cpython-312.pyc
│ │ │ │ │ │ ├── sphinxext.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── token.cpython-312.pyc
│ │ │ │ │ │ ├── unistring.cpython-312.pyc
│ │ │ │ │ │ └── util.cpython-312.pyc
│ │ │ │ │ ├── cmdline.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── filter.py
│ │ │ │ │ ├── filters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── formatter.py
│ │ │ │ │ ├── formatters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ ├── bbcode.cpython-312.pyc
│ │ │ │ │ │ │ ├── groff.cpython-312.pyc
│ │ │ │ │ │ │ ├── html.cpython-312.pyc
│ │ │ │ │ │ │ ├── img.cpython-312.pyc
│ │ │ │ │ │ │ ├── irc.cpython-312.pyc
│ │ │ │ │ │ │ ├── latex.cpython-312.pyc
│ │ │ │ │ │ │ ├── other.cpython-312.pyc
│ │ │ │ │ │ │ ├── pangomarkup.cpython-312.pyc
│ │ │ │ │ │ │ ├── rtf.cpython-312.pyc
│ │ │ │ │ │ │ ├── svg.cpython-312.pyc
│ │ │ │ │ │ │ ├── terminal.cpython-312.pyc
│ │ │ │ │ │ │ └── terminal256.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ ├── bbcode.py
│ │ │ │ │ │ ├── groff.py
│ │ │ │ │ │ ├── html.py
│ │ │ │ │ │ ├── img.py
│ │ │ │ │ │ ├── irc.py
│ │ │ │ │ │ ├── latex.py
│ │ │ │ │ │ ├── other.py
│ │ │ │ │ │ ├── pangomarkup.py
│ │ │ │ │ │ ├── rtf.py
│ │ │ │ │ │ ├── svg.py
│ │ │ │ │ │ ├── terminal.py
│ │ │ │ │ │ └── terminal256.py
│ │ │ │ │ ├── lexer.py
│ │ │ │ │ ├── lexers
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ └── python.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ └── python.py
│ │ │ │ │ ├── modeline.py
│ │ │ │ │ ├── plugin.py
│ │ │ │ │ ├── regexopt.py
│ │ │ │ │ ├── scanner.py
│ │ │ │ │ ├── sphinxext.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styles
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── _mapping.cpython-312.pyc
│ │ │ │ │ │ └── _mapping.py
│ │ │ │ │ ├── token.py
│ │ │ │ │ ├── unistring.py
│ │ │ │ │ └── util.py
│ │ │ │ ├── pyproject_hooks
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ └── _impl.cpython-312.pyc
│ │ │ │ │ ├── _compat.py
│ │ │ │ │ ├── _impl.py
│ │ │ │ │ └── _in_process
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── _in_process.cpython-312.pyc
│ │ │ │ │ └── _in_process.py
│ │ │ │ ├── requests
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ │ ├── __version__.py
│ │ │ │ │ ├── _internal_utils.py
│ │ │ │ │ ├── adapters.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── certs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── cookies.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── hooks.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ ├── packages.py
│ │ │ │ │ ├── sessions.py
│ │ │ │ │ ├── status_codes.py
│ │ │ │ │ ├── structures.py
│ │ │ │ │ └── utils.py
│ │ │ │ ├── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── providers.cpython-312.pyc
│ │ │ │ │ │ ├── reporters.cpython-312.pyc
│ │ │ │ │ │ ├── resolvers.cpython-312.pyc
│ │ │ │ │ │ └── structs.cpython-312.pyc
│ │ │ │ │ ├── compat
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── collections_abc.cpython-312.pyc
│ │ │ │ │ │ └── collections_abc.py
│ │ │ │ │ ├── providers.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── reporters.py
│ │ │ │ │ ├── resolvers.py
│ │ │ │ │ └── structs.py
│ │ │ │ ├── rich
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── _cell_widths.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_codes.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_replace.cpython-312.pyc
│ │ │ │ │ │ ├── _export_format.cpython-312.pyc
│ │ │ │ │ │ ├── _extension.cpython-312.pyc
│ │ │ │ │ │ ├── _fileno.cpython-312.pyc
│ │ │ │ │ │ ├── _inspect.cpython-312.pyc
│ │ │ │ │ │ ├── _log_render.cpython-312.pyc
│ │ │ │ │ │ ├── _loop.cpython-312.pyc
│ │ │ │ │ │ ├── _null_file.cpython-312.pyc
│ │ │ │ │ │ ├── _palettes.cpython-312.pyc
│ │ │ │ │ │ ├── _pick.cpython-312.pyc
│ │ │ │ │ │ ├── _ratio.cpython-312.pyc
│ │ │ │ │ │ ├── _spinners.cpython-312.pyc
│ │ │ │ │ │ ├── _stack.cpython-312.pyc
│ │ │ │ │ │ ├── _timer.cpython-312.pyc
│ │ │ │ │ │ ├── _win32_console.cpython-312.pyc
│ │ │ │ │ │ ├── _windows_renderer.cpython-312.pyc
│ │ │ │ │ │ ├── _windows.cpython-312.pyc
│ │ │ │ │ │ ├── _wrap.cpython-312.pyc
│ │ │ │ │ │ ├── abc.cpython-312.pyc
│ │ │ │ │ │ ├── align.cpython-312.pyc
│ │ │ │ │ │ ├── ansi.cpython-312.pyc
│ │ │ │ │ │ ├── bar.cpython-312.pyc
│ │ │ │ │ │ ├── box.cpython-312.pyc
│ │ │ │ │ │ ├── cells.cpython-312.pyc
│ │ │ │ │ │ ├── color_triplet.cpython-312.pyc
│ │ │ │ │ │ ├── color.cpython-312.pyc
│ │ │ │ │ │ ├── columns.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── constrain.cpython-312.pyc
│ │ │ │ │ │ ├── containers.cpython-312.pyc
│ │ │ │ │ │ ├── control.cpython-312.pyc
│ │ │ │ │ │ ├── default_styles.cpython-312.pyc
│ │ │ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ │ │ ├── emoji.cpython-312.pyc
│ │ │ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ │ │ ├── file_proxy.cpython-312.pyc
│ │ │ │ │ │ ├── filesize.cpython-312.pyc
│ │ │ │ │ │ ├── highlighter.cpython-312.pyc
│ │ │ │ │ │ ├── json.cpython-312.pyc
│ │ │ │ │ │ ├── jupyter.cpython-312.pyc
│ │ │ │ │ │ ├── layout.cpython-312.pyc
│ │ │ │ │ │ ├── live_render.cpython-312.pyc
│ │ │ │ │ │ ├── live.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── markup.cpython-312.pyc
│ │ │ │ │ │ ├── measure.cpython-312.pyc
│ │ │ │ │ │ ├── padding.cpython-312.pyc
│ │ │ │ │ │ ├── pager.cpython-312.pyc
│ │ │ │ │ │ ├── palette.cpython-312.pyc
│ │ │ │ │ │ ├── panel.cpython-312.pyc
│ │ │ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bar.cpython-312.pyc
│ │ │ │ │ │ ├── progress.cpython-312.pyc
│ │ │ │ │ │ ├── prompt.cpython-312.pyc
│ │ │ │ │ │ ├── protocol.cpython-312.pyc
│ │ │ │ │ │ ├── region.cpython-312.pyc
│ │ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ │ ├── rule.cpython-312.pyc
│ │ │ │ │ │ ├── scope.cpython-312.pyc
│ │ │ │ │ │ ├── screen.cpython-312.pyc
│ │ │ │ │ │ ├── segment.cpython-312.pyc
│ │ │ │ │ │ ├── spinner.cpython-312.pyc
│ │ │ │ │ │ ├── status.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── styled.cpython-312.pyc
│ │ │ │ │ │ ├── syntax.cpython-312.pyc
│ │ │ │ │ │ ├── table.cpython-312.pyc
│ │ │ │ │ │ ├── terminal_theme.cpython-312.pyc
│ │ │ │ │ │ ├── text.cpython-312.pyc
│ │ │ │ │ │ ├── theme.cpython-312.pyc
│ │ │ │ │ │ ├── themes.cpython-312.pyc
│ │ │ │ │ │ ├── traceback.cpython-312.pyc
│ │ │ │ │ │ └── tree.cpython-312.pyc
│ │ │ │ │ ├── _cell_widths.py
│ │ │ │ │ ├── _emoji_codes.py
│ │ │ │ │ ├── _emoji_replace.py
│ │ │ │ │ ├── _export_format.py
│ │ │ │ │ ├── _extension.py
│ │ │ │ │ ├── _fileno.py
│ │ │ │ │ ├── _inspect.py
│ │ │ │ │ ├── _log_render.py
│ │ │ │ │ ├── _loop.py
│ │ │ │ │ ├── _null_file.py
│ │ │ │ │ ├── _palettes.py
│ │ │ │ │ ├── _pick.py
│ │ │ │ │ ├── _ratio.py
│ │ │ │ │ ├── _spinners.py
│ │ │ │ │ ├── _stack.py
│ │ │ │ │ ├── _timer.py
│ │ │ │ │ ├── _win32_console.py
│ │ │ │ │ ├── _windows_renderer.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ ├── _wrap.py
│ │ │ │ │ ├── abc.py
│ │ │ │ │ ├── align.py
│ │ │ │ │ ├── ansi.py
│ │ │ │ │ ├── bar.py
│ │ │ │ │ ├── box.py
│ │ │ │ │ ├── cells.py
│ │ │ │ │ ├── color_triplet.py
│ │ │ │ │ ├── color.py
│ │ │ │ │ ├── columns.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── constrain.py
│ │ │ │ │ ├── containers.py
│ │ │ │ │ ├── control.py
│ │ │ │ │ ├── default_styles.py
│ │ │ │ │ ├── diagnose.py
│ │ │ │ │ ├── emoji.py
│ │ │ │ │ ├── errors.py
│ │ │ │ │ ├── file_proxy.py
│ │ │ │ │ ├── filesize.py
│ │ │ │ │ ├── highlighter.py
│ │ │ │ │ ├── json.py
│ │ │ │ │ ├── jupyter.py
│ │ │ │ │ ├── layout.py
│ │ │ │ │ ├── live_render.py
│ │ │ │ │ ├── live.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── markup.py
│ │ │ │ │ ├── measure.py
│ │ │ │ │ ├── padding.py
│ │ │ │ │ ├── pager.py
│ │ │ │ │ ├── palette.py
│ │ │ │ │ ├── panel.py
│ │ │ │ │ ├── pretty.py
│ │ │ │ │ ├── progress_bar.py
│ │ │ │ │ ├── progress.py
│ │ │ │ │ ├── prompt.py
│ │ │ │ │ ├── protocol.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── region.py
│ │ │ │ │ ├── repr.py
│ │ │ │ │ ├── rule.py
│ │ │ │ │ ├── scope.py
│ │ │ │ │ ├── screen.py
│ │ │ │ │ ├── segment.py
│ │ │ │ │ ├── spinner.py
│ │ │ │ │ ├── status.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styled.py
│ │ │ │ │ ├── syntax.py
│ │ │ │ │ ├── table.py
│ │ │ │ │ ├── terminal_theme.py
│ │ │ │ │ ├── text.py
│ │ │ │ │ ├── theme.py
│ │ │ │ │ ├── themes.py
│ │ │ │ │ ├── traceback.py
│ │ │ │ │ └── tree.py
│ │ │ │ ├── tomli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _re.cpython-312.pyc
│ │ │ │ │ │ └── _types.cpython-312.pyc
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _re.py
│ │ │ │ │ ├── _types.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── truststore
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _api.cpython-312.pyc
│ │ │ │ │ │ ├── _macos.cpython-312.pyc
│ │ │ │ │ │ ├── _openssl.cpython-312.pyc
│ │ │ │ │ │ ├── _ssl_constants.cpython-312.pyc
│ │ │ │ │ │ └── _windows.cpython-312.pyc
│ │ │ │ │ ├── _api.py
│ │ │ │ │ ├── _macos.py
│ │ │ │ │ ├── _openssl.py
│ │ │ │ │ ├── _ssl_constants.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── typing_extensions.py
│ │ │ │ ├── urllib3
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── _collections.py
│ │ │ │ │ ├── _version.py
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── connectionpool.py
│ │ │ │ │ ├── contrib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _appengine_environ.cpython-312.pyc
│ │ │ │ │ │ │ ├── appengine.cpython-312.pyc
│ │ │ │ │ │ │ ├── ntlmpool.cpython-312.pyc
│ │ │ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ │ │ ├── securetransport.cpython-312.pyc
│ │ │ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ │ │ ├── _appengine_environ.py
│ │ │ │ │ │ ├── _securetransport
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── bindings.cpython-312.pyc
│ │ │ │ │ │ │ │ └── low_level.cpython-312.pyc
│ │ │ │ │ │ │ ├── bindings.py
│ │ │ │ │ │ │ └── low_level.py
│ │ │ │ │ │ ├── appengine.py
│ │ │ │ │ │ ├── ntlmpool.py
│ │ │ │ │ │ ├── pyopenssl.py
│ │ │ │ │ │ ├── securetransport.py
│ │ │ │ │ │ └── socks.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── fields.py
│ │ │ │ │ ├── filepost.py
│ │ │ │ │ ├── packages
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── six.cpython-312.pyc
│ │ │ │ │ │ ├── backports
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── makefile.cpython-312.pyc
│ │ │ │ │ │ │ │ └── weakref_finalize.cpython-312.pyc
│ │ │ │ │ │ │ ├── makefile.py
│ │ │ │ │ │ │ └── weakref_finalize.py
│ │ │ │ │ │ └── six.py
│ │ │ │ │ ├── poolmanager.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ └── util
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ │ │ ├── queue.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ │ │ └── wait.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── proxy.py
│ │ │ │ │ ├── queue.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── ssl_.py
│ │ │ │ │ ├── ssl_match_hostname.py
│ │ │ │ │ ├── ssltransport.py
│ │ │ │ │ ├── timeout.py
│ │ │ │ │ ├── url.py
│ │ │ │ │ └── wait.py
│ │ │ │ └── vendor.txt
│ │ │ └── py.typed
│ │ ├── pip-24.2.dist-info
│ │ │ ├── AUTHORS.txt
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── requests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── __version__.py
│ │ │ ├── _internal_utils.py
│ │ │ ├── adapters.py
│ │ │ ├── api.py
│ │ │ ├── auth.py
│ │ │ ├── certs.py
│ │ │ ├── compat.py
│ │ │ ├── cookies.py
│ │ │ ├── exceptions.py
│ │ │ ├── help.py
│ │ │ ├── hooks.py
│ │ │ ├── models.py
│ │ │ ├── packages.py
│ │ │ ├── sessions.py
│ │ │ ├── status_codes.py
│ │ │ ├── structures.py
│ │ │ └── utils.py
│ │ ├── requests-2.32.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── soupsieve
│ │ │ ├── __init__.py
│ │ │ ├── __meta__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __meta__.cpython-312.pyc
│ │ │ │ ├── css_match.cpython-312.pyc
│ │ │ │ ├── css_parser.cpython-312.pyc
│ │ │ │ ├── css_types.cpython-312.pyc
│ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ └── util.cpython-312.pyc
│ │ │ ├── css_match.py
│ │ │ ├── css_parser.py
│ │ │ ├── css_types.py
│ │ │ ├── pretty.py
│ │ │ ├── py.typed
│ │ │ └── util.py
│ │ ├── soupsieve-2.6.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── urllib3
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _base_connection.cpython-312.pyc
│ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ ├── _request_methods.cpython-312.pyc
│ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ └── response.cpython-312.pyc
│ │ │ ├── _base_connection.py
│ │ │ ├── _collections.py
│ │ │ ├── _request_methods.py
│ │ │ ├── _version.py
│ │ │ ├── connection.py
│ │ │ ├── connectionpool.py
│ │ │ ├── contrib
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ ├── emscripten
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── fetch.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── emscripten_fetch_worker.js
│ │ │ │ │ ├── fetch.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ └── response.py
│ │ │ │ ├── pyopenssl.py
│ │ │ │ └── socks.py
│ │ │ ├── exceptions.py
│ │ │ ├── fields.py
│ │ │ ├── filepost.py
│ │ │ ├── http2
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ └── probe.cpython-312.pyc
│ │ │ │ ├── connection.py
│ │ │ │ └── probe.py
│ │ │ ├── poolmanager.py
│ │ │ ├── py.typed
│ │ │ ├── response.py
│ │ │ └── util
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ └── wait.cpython-312.pyc
│ │ │ ├── connection.py
│ │ │ ├── proxy.py
│ │ │ ├── request.py
│ │ │ ├── response.py
│ │ │ ├── retry.py
│ │ │ ├── ssl_.py
│ │ │ ├── ssl_match_hostname.py
│ │ │ ├── ssltransport.py
│ │ │ ├── timeout.py
│ │ │ ├── url.py
│ │ │ ├── util.py
│ │ │ └── wait.py
│ │ ├── urllib3-2.2.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── useragent
│ │ │ ├── __init__.py
│ │ │ ├── __init__.pyc
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── resources
│ │ │ │ └── user_agent_data.json
│ │ │ └── test
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── test_additional_os.json
│ │ │ ├── test_browser.json
│ │ │ ├── test_device.json
│ │ │ ├── test_firefox.json
│ │ │ ├── test_os.json
│ │ │ └── test_pgts_browser.json
│ │ ├── useragent-0.1.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── werkzeug
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _internal.cpython-312.pyc
│ │ │ │ ├── _reloader.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formparser.cpython-312.pyc
│ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ ├── local.cpython-312.pyc
│ │ │ │ ├── security.cpython-312.pyc
│ │ │ │ ├── serving.cpython-312.pyc
│ │ │ │ ├── test.cpython-312.pyc
│ │ │ │ ├── testapp.cpython-312.pyc
│ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ ├── user_agent.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── wsgi.cpython-312.pyc
│ │ │ ├── _internal.py
│ │ │ ├── _reloader.py
│ │ │ ├── datastructures
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── accept.cpython-312.pyc
│ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ ├── cache_control.cpython-312.pyc
│ │ │ │ │ ├── csp.cpython-312.pyc
│ │ │ │ │ ├── etag.cpython-312.pyc
│ │ │ │ │ ├── file_storage.cpython-312.pyc
│ │ │ │ │ ├── headers.cpython-312.pyc
│ │ │ │ │ ├── mixins.cpython-312.pyc
│ │ │ │ │ ├── range.cpython-312.pyc
│ │ │ │ │ └── structures.cpython-312.pyc
│ │ │ │ ├── accept.py
│ │ │ │ ├── accept.pyi
│ │ │ │ ├── auth.py
│ │ │ │ ├── cache_control.py
│ │ │ │ ├── cache_control.pyi
│ │ │ │ ├── csp.py
│ │ │ │ ├── csp.pyi
│ │ │ │ ├── etag.py
│ │ │ │ ├── etag.pyi
│ │ │ │ ├── file_storage.py
│ │ │ │ ├── file_storage.pyi
│ │ │ │ ├── headers.py
│ │ │ │ ├── headers.pyi
│ │ │ │ ├── mixins.py
│ │ │ │ ├── mixins.pyi
│ │ │ │ ├── range.py
│ │ │ │ ├── range.pyi
│ │ │ │ ├── structures.py
│ │ │ │ └── structures.pyi
│ │ │ ├── debug
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ └── tbtools.cpython-312.pyc
│ │ │ │ ├── console.py
│ │ │ │ ├── repr.py
│ │ │ │ ├── shared
│ │ │ │ │ ├── console.png
│ │ │ │ │ ├── debugger.js
│ │ │ │ │ ├── ICON_LICENSE.md
│ │ │ │ │ ├── less.png
│ │ │ │ │ ├── more.png
│ │ │ │ │ └── style.css
│ │ │ │ └── tbtools.py
│ │ │ ├── exceptions.py
│ │ │ ├── formparser.py
│ │ │ ├── http.py
│ │ │ ├── local.py
│ │ │ ├── middleware
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── dispatcher.cpython-312.pyc
│ │ │ │ │ ├── http_proxy.cpython-312.pyc
│ │ │ │ │ ├── lint.cpython-312.pyc
│ │ │ │ │ ├── profiler.cpython-312.pyc
│ │ │ │ │ ├── proxy_fix.cpython-312.pyc
│ │ │ │ │ └── shared_data.cpython-312.pyc
│ │ │ │ ├── dispatcher.py
│ │ │ │ ├── http_proxy.py
│ │ │ │ ├── lint.py
│ │ │ │ ├── profiler.py
│ │ │ │ ├── proxy_fix.py
│ │ │ │ └── shared_data.py
│ │ │ ├── py.typed
│ │ │ ├── routing
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── converters.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── map.cpython-312.pyc
│ │ │ │ │ ├── matcher.cpython-312.pyc
│ │ │ │ │ └── rules.cpython-312.pyc
│ │ │ │ ├── converters.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── map.py
│ │ │ │ ├── matcher.py
│ │ │ │ └── rules.py
│ │ │ ├── sansio
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ │ ├── multipart.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ ├── http.py
│ │ │ │ ├── multipart.py
│ │ │ │ ├── request.py
│ │ │ │ ├── response.py
│ │ │ │ └── utils.py
│ │ │ ├── security.py
│ │ │ ├── serving.py
│ │ │ ├── test.py
│ │ │ ├── testapp.py
│ │ │ ├── urls.py
│ │ │ ├── user_agent.py
│ │ │ ├── utils.py
│ │ │ ├── wrappers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ ├── request.py
│ │ │ │ └── response.py
│ │ │ └── wsgi.py
│ │ └── werkzeug-3.0.4.dist-info
│ │ ├── INSTALLER
│ │ ├── LICENSE.txt
│ │ ├── METADATA
│ │ ├── RECORD
│ │ └── WHEEL
│ ├── pyvenv.cfg
│ ├── static
│ │ └── styles.css
│ ├── templates
│ │ └── index.html
│ └── test.py
├── cline_config.json
├── mcp_server.py
├── README.md
├── search_results.json
├── settings.json
└── test_files
├── text1.txt
└── text2.txt
```
# Files
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/commands/download.py:
--------------------------------------------------------------------------------
```python
1 | import logging
2 | import os
3 | from optparse import Values
4 | from typing import List
5 |
6 | from pip._internal.cli import cmdoptions
7 | from pip._internal.cli.cmdoptions import make_target_python
8 | from pip._internal.cli.req_command import RequirementCommand, with_cleanup
9 | from pip._internal.cli.status_codes import SUCCESS
10 | from pip._internal.operations.build.build_tracker import get_build_tracker
11 | from pip._internal.req.req_install import check_legacy_setup_py_options
12 | from pip._internal.utils.misc import ensure_dir, normalize_path, write_output
13 | from pip._internal.utils.temp_dir import TempDirectory
14 |
15 | logger = logging.getLogger(__name__)
16 |
17 |
18 | class DownloadCommand(RequirementCommand):
19 | """
20 | Download packages from:
21 |
22 | - PyPI (and other indexes) using requirement specifiers.
23 | - VCS project urls.
24 | - Local project directories.
25 | - Local or remote source archives.
26 |
27 | pip also supports downloading from "requirements files", which provide
28 | an easy way to specify a whole environment to be downloaded.
29 | """
30 |
31 | usage = """
32 | %prog [options] <requirement specifier> [package-index-options] ...
33 | %prog [options] -r <requirements file> [package-index-options] ...
34 | %prog [options] <vcs project url> ...
35 | %prog [options] <local project path> ...
36 | %prog [options] <archive url/path> ..."""
37 |
38 | def add_options(self) -> None:
39 | self.cmd_opts.add_option(cmdoptions.constraints())
40 | self.cmd_opts.add_option(cmdoptions.requirements())
41 | self.cmd_opts.add_option(cmdoptions.no_deps())
42 | self.cmd_opts.add_option(cmdoptions.global_options())
43 | self.cmd_opts.add_option(cmdoptions.no_binary())
44 | self.cmd_opts.add_option(cmdoptions.only_binary())
45 | self.cmd_opts.add_option(cmdoptions.prefer_binary())
46 | self.cmd_opts.add_option(cmdoptions.src())
47 | self.cmd_opts.add_option(cmdoptions.pre())
48 | self.cmd_opts.add_option(cmdoptions.require_hashes())
49 | self.cmd_opts.add_option(cmdoptions.progress_bar())
50 | self.cmd_opts.add_option(cmdoptions.no_build_isolation())
51 | self.cmd_opts.add_option(cmdoptions.use_pep517())
52 | self.cmd_opts.add_option(cmdoptions.no_use_pep517())
53 | self.cmd_opts.add_option(cmdoptions.check_build_deps())
54 | self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
55 |
56 | self.cmd_opts.add_option(
57 | "-d",
58 | "--dest",
59 | "--destination-dir",
60 | "--destination-directory",
61 | dest="download_dir",
62 | metavar="dir",
63 | default=os.curdir,
64 | help="Download packages into <dir>.",
65 | )
66 |
67 | cmdoptions.add_target_python_options(self.cmd_opts)
68 |
69 | index_opts = cmdoptions.make_option_group(
70 | cmdoptions.index_group,
71 | self.parser,
72 | )
73 |
74 | self.parser.insert_option_group(0, index_opts)
75 | self.parser.insert_option_group(0, self.cmd_opts)
76 |
77 | @with_cleanup
78 | def run(self, options: Values, args: List[str]) -> int:
79 | options.ignore_installed = True
80 | # editable doesn't really make sense for `pip download`, but the bowels
81 | # of the RequirementSet code require that property.
82 | options.editables = []
83 |
84 | cmdoptions.check_dist_restriction(options)
85 |
86 | options.download_dir = normalize_path(options.download_dir)
87 | ensure_dir(options.download_dir)
88 |
89 | session = self.get_default_session(options)
90 |
91 | target_python = make_target_python(options)
92 | finder = self._build_package_finder(
93 | options=options,
94 | session=session,
95 | target_python=target_python,
96 | ignore_requires_python=options.ignore_requires_python,
97 | )
98 |
99 | build_tracker = self.enter_context(get_build_tracker())
100 |
101 | directory = TempDirectory(
102 | delete=not options.no_clean,
103 | kind="download",
104 | globally_managed=True,
105 | )
106 |
107 | reqs = self.get_requirements(args, options, finder, session)
108 | check_legacy_setup_py_options(options, reqs)
109 |
110 | preparer = self.make_requirement_preparer(
111 | temp_build_dir=directory,
112 | options=options,
113 | build_tracker=build_tracker,
114 | session=session,
115 | finder=finder,
116 | download_dir=options.download_dir,
117 | use_user_site=False,
118 | verbosity=self.verbosity,
119 | )
120 |
121 | resolver = self.make_resolver(
122 | preparer=preparer,
123 | finder=finder,
124 | options=options,
125 | ignore_requires_python=options.ignore_requires_python,
126 | use_pep517=options.use_pep517,
127 | py_version_info=options.python_version,
128 | )
129 |
130 | self.trace_basic_info(finder)
131 |
132 | requirement_set = resolver.resolve(reqs, check_supported_wheels=True)
133 |
134 | downloaded: List[str] = []
135 | for req in requirement_set.requirements.values():
136 | if req.satisfied_by is None:
137 | assert req.name is not None
138 | preparer.save_linked_requirement(req)
139 | downloaded.append(req.name)
140 |
141 | preparer.prepare_linked_requirements_more(requirement_set.requirements.values())
142 |
143 | if downloaded:
144 | write_output("Successfully downloaded %s", " ".join(downloaded))
145 |
146 | return SUCCESS
147 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/packaging/_tokenizer.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import contextlib
4 | import re
5 | from dataclasses import dataclass
6 | from typing import Iterator, NoReturn
7 |
8 | from .specifiers import Specifier
9 |
10 |
11 | @dataclass
12 | class Token:
13 | name: str
14 | text: str
15 | position: int
16 |
17 |
18 | class ParserSyntaxError(Exception):
19 | """The provided source text could not be parsed correctly."""
20 |
21 | def __init__(
22 | self,
23 | message: str,
24 | *,
25 | source: str,
26 | span: tuple[int, int],
27 | ) -> None:
28 | self.span = span
29 | self.message = message
30 | self.source = source
31 |
32 | super().__init__()
33 |
34 | def __str__(self) -> str:
35 | marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^"
36 | return "\n ".join([self.message, self.source, marker])
37 |
38 |
39 | DEFAULT_RULES: dict[str, str | re.Pattern[str]] = {
40 | "LEFT_PARENTHESIS": r"\(",
41 | "RIGHT_PARENTHESIS": r"\)",
42 | "LEFT_BRACKET": r"\[",
43 | "RIGHT_BRACKET": r"\]",
44 | "SEMICOLON": r";",
45 | "COMMA": r",",
46 | "QUOTED_STRING": re.compile(
47 | r"""
48 | (
49 | ('[^']*')
50 | |
51 | ("[^"]*")
52 | )
53 | """,
54 | re.VERBOSE,
55 | ),
56 | "OP": r"(===|==|~=|!=|<=|>=|<|>)",
57 | "BOOLOP": r"\b(or|and)\b",
58 | "IN": r"\bin\b",
59 | "NOT": r"\bnot\b",
60 | "VARIABLE": re.compile(
61 | r"""
62 | \b(
63 | python_version
64 | |python_full_version
65 | |os[._]name
66 | |sys[._]platform
67 | |platform_(release|system)
68 | |platform[._](version|machine|python_implementation)
69 | |python_implementation
70 | |implementation_(name|version)
71 | |extra
72 | )\b
73 | """,
74 | re.VERBOSE,
75 | ),
76 | "SPECIFIER": re.compile(
77 | Specifier._operator_regex_str + Specifier._version_regex_str,
78 | re.VERBOSE | re.IGNORECASE,
79 | ),
80 | "AT": r"\@",
81 | "URL": r"[^ \t]+",
82 | "IDENTIFIER": r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b",
83 | "VERSION_PREFIX_TRAIL": r"\.\*",
84 | "VERSION_LOCAL_LABEL_TRAIL": r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*",
85 | "WS": r"[ \t]+",
86 | "END": r"$",
87 | }
88 |
89 |
90 | class Tokenizer:
91 | """Context-sensitive token parsing.
92 |
93 | Provides methods to examine the input stream to check whether the next token
94 | matches.
95 | """
96 |
97 | def __init__(
98 | self,
99 | source: str,
100 | *,
101 | rules: dict[str, str | re.Pattern[str]],
102 | ) -> None:
103 | self.source = source
104 | self.rules: dict[str, re.Pattern[str]] = {
105 | name: re.compile(pattern) for name, pattern in rules.items()
106 | }
107 | self.next_token: Token | None = None
108 | self.position = 0
109 |
110 | def consume(self, name: str) -> None:
111 | """Move beyond provided token name, if at current position."""
112 | if self.check(name):
113 | self.read()
114 |
115 | def check(self, name: str, *, peek: bool = False) -> bool:
116 | """Check whether the next token has the provided name.
117 |
118 | By default, if the check succeeds, the token *must* be read before
119 | another check. If `peek` is set to `True`, the token is not loaded and
120 | would need to be checked again.
121 | """
122 | assert (
123 | self.next_token is None
124 | ), f"Cannot check for {name!r}, already have {self.next_token!r}"
125 | assert name in self.rules, f"Unknown token name: {name!r}"
126 |
127 | expression = self.rules[name]
128 |
129 | match = expression.match(self.source, self.position)
130 | if match is None:
131 | return False
132 | if not peek:
133 | self.next_token = Token(name, match[0], self.position)
134 | return True
135 |
136 | def expect(self, name: str, *, expected: str) -> Token:
137 | """Expect a certain token name next, failing with a syntax error otherwise.
138 |
139 | The token is *not* read.
140 | """
141 | if not self.check(name):
142 | raise self.raise_syntax_error(f"Expected {expected}")
143 | return self.read()
144 |
145 | def read(self) -> Token:
146 | """Consume the next token and return it."""
147 | token = self.next_token
148 | assert token is not None
149 |
150 | self.position += len(token.text)
151 | self.next_token = None
152 |
153 | return token
154 |
155 | def raise_syntax_error(
156 | self,
157 | message: str,
158 | *,
159 | span_start: int | None = None,
160 | span_end: int | None = None,
161 | ) -> NoReturn:
162 | """Raise ParserSyntaxError at the given position."""
163 | span = (
164 | self.position if span_start is None else span_start,
165 | self.position if span_end is None else span_end,
166 | )
167 | raise ParserSyntaxError(
168 | message,
169 | source=self.source,
170 | span=span,
171 | )
172 |
173 | @contextlib.contextmanager
174 | def enclosing_tokens(
175 | self, open_token: str, close_token: str, *, around: str
176 | ) -> Iterator[None]:
177 | if self.check(open_token):
178 | open_position = self.position
179 | self.read()
180 | else:
181 | open_position = None
182 |
183 | yield
184 |
185 | if open_position is None:
186 | return
187 |
188 | if not self.check(close_token):
189 | self.raise_syntax_error(
190 | f"Expected matching {close_token} for {open_token}, after {around}",
191 | span_start=open_position,
192 | )
193 |
194 | self.read()
195 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/packaging/utils.py:
--------------------------------------------------------------------------------
```python
1 | # This file is dual licensed under the terms of the Apache License, Version
2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3 | # for complete details.
4 |
5 | from __future__ import annotations
6 |
7 | import re
8 | from typing import NewType, Tuple, Union, cast
9 |
10 | from .tags import Tag, parse_tag
11 | from .version import InvalidVersion, Version
12 |
13 | BuildTag = Union[Tuple[()], Tuple[int, str]]
14 | NormalizedName = NewType("NormalizedName", str)
15 |
16 |
17 | class InvalidName(ValueError):
18 | """
19 | An invalid distribution name; users should refer to the packaging user guide.
20 | """
21 |
22 |
23 | class InvalidWheelFilename(ValueError):
24 | """
25 | An invalid wheel filename was found, users should refer to PEP 427.
26 | """
27 |
28 |
29 | class InvalidSdistFilename(ValueError):
30 | """
31 | An invalid sdist filename was found, users should refer to the packaging user guide.
32 | """
33 |
34 |
35 | # Core metadata spec for `Name`
36 | _validate_regex = re.compile(
37 | r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE
38 | )
39 | _canonicalize_regex = re.compile(r"[-_.]+")
40 | _normalized_regex = re.compile(r"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$")
41 | # PEP 427: The build number must start with a digit.
42 | _build_tag_regex = re.compile(r"(\d+)(.*)")
43 |
44 |
45 | def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
46 | if validate and not _validate_regex.match(name):
47 | raise InvalidName(f"name is invalid: {name!r}")
48 | # This is taken from PEP 503.
49 | value = _canonicalize_regex.sub("-", name).lower()
50 | return cast(NormalizedName, value)
51 |
52 |
53 | def is_normalized_name(name: str) -> bool:
54 | return _normalized_regex.match(name) is not None
55 |
56 |
57 | def canonicalize_version(
58 | version: Version | str, *, strip_trailing_zero: bool = True
59 | ) -> str:
60 | """
61 | This is very similar to Version.__str__, but has one subtle difference
62 | with the way it handles the release segment.
63 | """
64 | if isinstance(version, str):
65 | try:
66 | parsed = Version(version)
67 | except InvalidVersion:
68 | # Legacy versions cannot be normalized
69 | return version
70 | else:
71 | parsed = version
72 |
73 | parts = []
74 |
75 | # Epoch
76 | if parsed.epoch != 0:
77 | parts.append(f"{parsed.epoch}!")
78 |
79 | # Release segment
80 | release_segment = ".".join(str(x) for x in parsed.release)
81 | if strip_trailing_zero:
82 | # NB: This strips trailing '.0's to normalize
83 | release_segment = re.sub(r"(\.0)+$", "", release_segment)
84 | parts.append(release_segment)
85 |
86 | # Pre-release
87 | if parsed.pre is not None:
88 | parts.append("".join(str(x) for x in parsed.pre))
89 |
90 | # Post-release
91 | if parsed.post is not None:
92 | parts.append(f".post{parsed.post}")
93 |
94 | # Development release
95 | if parsed.dev is not None:
96 | parts.append(f".dev{parsed.dev}")
97 |
98 | # Local version segment
99 | if parsed.local is not None:
100 | parts.append(f"+{parsed.local}")
101 |
102 | return "".join(parts)
103 |
104 |
105 | def parse_wheel_filename(
106 | filename: str,
107 | ) -> tuple[NormalizedName, Version, BuildTag, frozenset[Tag]]:
108 | if not filename.endswith(".whl"):
109 | raise InvalidWheelFilename(
110 | f"Invalid wheel filename (extension must be '.whl'): {filename}"
111 | )
112 |
113 | filename = filename[:-4]
114 | dashes = filename.count("-")
115 | if dashes not in (4, 5):
116 | raise InvalidWheelFilename(
117 | f"Invalid wheel filename (wrong number of parts): {filename}"
118 | )
119 |
120 | parts = filename.split("-", dashes - 2)
121 | name_part = parts[0]
122 | # See PEP 427 for the rules on escaping the project name.
123 | if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None:
124 | raise InvalidWheelFilename(f"Invalid project name: {filename}")
125 | name = canonicalize_name(name_part)
126 |
127 | try:
128 | version = Version(parts[1])
129 | except InvalidVersion as e:
130 | raise InvalidWheelFilename(
131 | f"Invalid wheel filename (invalid version): {filename}"
132 | ) from e
133 |
134 | if dashes == 5:
135 | build_part = parts[2]
136 | build_match = _build_tag_regex.match(build_part)
137 | if build_match is None:
138 | raise InvalidWheelFilename(
139 | f"Invalid build number: {build_part} in '{filename}'"
140 | )
141 | build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2)))
142 | else:
143 | build = ()
144 | tags = parse_tag(parts[-1])
145 | return (name, version, build, tags)
146 |
147 |
148 | def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]:
149 | if filename.endswith(".tar.gz"):
150 | file_stem = filename[: -len(".tar.gz")]
151 | elif filename.endswith(".zip"):
152 | file_stem = filename[: -len(".zip")]
153 | else:
154 | raise InvalidSdistFilename(
155 | f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):"
156 | f" {filename}"
157 | )
158 |
159 | # We are requiring a PEP 440 version, which cannot contain dashes,
160 | # so we split on the last dash.
161 | name_part, sep, version_part = file_stem.rpartition("-")
162 | if not sep:
163 | raise InvalidSdistFilename(f"Invalid sdist filename: {filename}")
164 |
165 | name = canonicalize_name(name_part)
166 |
167 | try:
168 | version = Version(version_part)
169 | except InvalidVersion as e:
170 | raise InvalidSdistFilename(
171 | f"Invalid sdist filename (invalid version): {filename}"
172 | ) from e
173 |
174 | return (name, version)
175 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/rich/measure.py:
--------------------------------------------------------------------------------
```python
1 | from operator import itemgetter
2 | from typing import TYPE_CHECKING, Callable, NamedTuple, Optional, Sequence
3 |
4 | from . import errors
5 | from .protocol import is_renderable, rich_cast
6 |
7 | if TYPE_CHECKING:
8 | from .console import Console, ConsoleOptions, RenderableType
9 |
10 |
11 | class Measurement(NamedTuple):
12 | """Stores the minimum and maximum widths (in characters) required to render an object."""
13 |
14 | minimum: int
15 | """Minimum number of cells required to render."""
16 | maximum: int
17 | """Maximum number of cells required to render."""
18 |
19 | @property
20 | def span(self) -> int:
21 | """Get difference between maximum and minimum."""
22 | return self.maximum - self.minimum
23 |
24 | def normalize(self) -> "Measurement":
25 | """Get measurement that ensures that minimum <= maximum and minimum >= 0
26 |
27 | Returns:
28 | Measurement: A normalized measurement.
29 | """
30 | minimum, maximum = self
31 | minimum = min(max(0, minimum), maximum)
32 | return Measurement(max(0, minimum), max(0, max(minimum, maximum)))
33 |
34 | def with_maximum(self, width: int) -> "Measurement":
35 | """Get a RenderableWith where the widths are <= width.
36 |
37 | Args:
38 | width (int): Maximum desired width.
39 |
40 | Returns:
41 | Measurement: New Measurement object.
42 | """
43 | minimum, maximum = self
44 | return Measurement(min(minimum, width), min(maximum, width))
45 |
46 | def with_minimum(self, width: int) -> "Measurement":
47 | """Get a RenderableWith where the widths are >= width.
48 |
49 | Args:
50 | width (int): Minimum desired width.
51 |
52 | Returns:
53 | Measurement: New Measurement object.
54 | """
55 | minimum, maximum = self
56 | width = max(0, width)
57 | return Measurement(max(minimum, width), max(maximum, width))
58 |
59 | def clamp(
60 | self, min_width: Optional[int] = None, max_width: Optional[int] = None
61 | ) -> "Measurement":
62 | """Clamp a measurement within the specified range.
63 |
64 | Args:
65 | min_width (int): Minimum desired width, or ``None`` for no minimum. Defaults to None.
66 | max_width (int): Maximum desired width, or ``None`` for no maximum. Defaults to None.
67 |
68 | Returns:
69 | Measurement: New Measurement object.
70 | """
71 | measurement = self
72 | if min_width is not None:
73 | measurement = measurement.with_minimum(min_width)
74 | if max_width is not None:
75 | measurement = measurement.with_maximum(max_width)
76 | return measurement
77 |
78 | @classmethod
79 | def get(
80 | cls, console: "Console", options: "ConsoleOptions", renderable: "RenderableType"
81 | ) -> "Measurement":
82 | """Get a measurement for a renderable.
83 |
84 | Args:
85 | console (~rich.console.Console): Console instance.
86 | options (~rich.console.ConsoleOptions): Console options.
87 | renderable (RenderableType): An object that may be rendered with Rich.
88 |
89 | Raises:
90 | errors.NotRenderableError: If the object is not renderable.
91 |
92 | Returns:
93 | Measurement: Measurement object containing range of character widths required to render the object.
94 | """
95 | _max_width = options.max_width
96 | if _max_width < 1:
97 | return Measurement(0, 0)
98 | if isinstance(renderable, str):
99 | renderable = console.render_str(
100 | renderable, markup=options.markup, highlight=False
101 | )
102 | renderable = rich_cast(renderable)
103 | if is_renderable(renderable):
104 | get_console_width: Optional[
105 | Callable[["Console", "ConsoleOptions"], "Measurement"]
106 | ] = getattr(renderable, "__rich_measure__", None)
107 | if get_console_width is not None:
108 | render_width = (
109 | get_console_width(console, options)
110 | .normalize()
111 | .with_maximum(_max_width)
112 | )
113 | if render_width.maximum < 1:
114 | return Measurement(0, 0)
115 | return render_width.normalize()
116 | else:
117 | return Measurement(0, _max_width)
118 | else:
119 | raise errors.NotRenderableError(
120 | f"Unable to get render width for {renderable!r}; "
121 | "a str, Segment, or object with __rich_console__ method is required"
122 | )
123 |
124 |
125 | def measure_renderables(
126 | console: "Console",
127 | options: "ConsoleOptions",
128 | renderables: Sequence["RenderableType"],
129 | ) -> "Measurement":
130 | """Get a measurement that would fit a number of renderables.
131 |
132 | Args:
133 | console (~rich.console.Console): Console instance.
134 | options (~rich.console.ConsoleOptions): Console options.
135 | renderables (Iterable[RenderableType]): One or more renderable objects.
136 |
137 | Returns:
138 | Measurement: Measurement object containing range of character widths required to
139 | contain all given renderables.
140 | """
141 | if not renderables:
142 | return Measurement(0, 0)
143 | get_measurement = Measurement.get
144 | measurements = [
145 | get_measurement(console, options, renderable) for renderable in renderables
146 | ]
147 | measured_width = Measurement(
148 | max(measurements, key=itemgetter(0)).minimum,
149 | max(measurements, key=itemgetter(1)).maximum,
150 | )
151 | return measured_width
152 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/datastructures/mixins.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | from itertools import repeat
4 |
5 | from .._internal import _missing
6 |
7 |
8 | def is_immutable(self):
9 | raise TypeError(f"{type(self).__name__!r} objects are immutable")
10 |
11 |
12 | class ImmutableListMixin:
13 | """Makes a :class:`list` immutable.
14 |
15 | .. versionadded:: 0.5
16 |
17 | :private:
18 | """
19 |
20 | _hash_cache = None
21 |
22 | def __hash__(self):
23 | if self._hash_cache is not None:
24 | return self._hash_cache
25 | rv = self._hash_cache = hash(tuple(self))
26 | return rv
27 |
28 | def __reduce_ex__(self, protocol):
29 | return type(self), (list(self),)
30 |
31 | def __delitem__(self, key):
32 | is_immutable(self)
33 |
34 | def __iadd__(self, other):
35 | is_immutable(self)
36 |
37 | def __imul__(self, other):
38 | is_immutable(self)
39 |
40 | def __setitem__(self, key, value):
41 | is_immutable(self)
42 |
43 | def append(self, item):
44 | is_immutable(self)
45 |
46 | def remove(self, item):
47 | is_immutable(self)
48 |
49 | def extend(self, iterable):
50 | is_immutable(self)
51 |
52 | def insert(self, pos, value):
53 | is_immutable(self)
54 |
55 | def pop(self, index=-1):
56 | is_immutable(self)
57 |
58 | def reverse(self):
59 | is_immutable(self)
60 |
61 | def sort(self, key=None, reverse=False):
62 | is_immutable(self)
63 |
64 |
65 | class ImmutableDictMixin:
66 | """Makes a :class:`dict` immutable.
67 |
68 | .. versionadded:: 0.5
69 |
70 | :private:
71 | """
72 |
73 | _hash_cache = None
74 |
75 | @classmethod
76 | def fromkeys(cls, keys, value=None):
77 | instance = super().__new__(cls)
78 | instance.__init__(zip(keys, repeat(value)))
79 | return instance
80 |
81 | def __reduce_ex__(self, protocol):
82 | return type(self), (dict(self),)
83 |
84 | def _iter_hashitems(self):
85 | return self.items()
86 |
87 | def __hash__(self):
88 | if self._hash_cache is not None:
89 | return self._hash_cache
90 | rv = self._hash_cache = hash(frozenset(self._iter_hashitems()))
91 | return rv
92 |
93 | def setdefault(self, key, default=None):
94 | is_immutable(self)
95 |
96 | def update(self, *args, **kwargs):
97 | is_immutable(self)
98 |
99 | def pop(self, key, default=None):
100 | is_immutable(self)
101 |
102 | def popitem(self):
103 | is_immutable(self)
104 |
105 | def __setitem__(self, key, value):
106 | is_immutable(self)
107 |
108 | def __delitem__(self, key):
109 | is_immutable(self)
110 |
111 | def clear(self):
112 | is_immutable(self)
113 |
114 |
115 | class ImmutableMultiDictMixin(ImmutableDictMixin):
116 | """Makes a :class:`MultiDict` immutable.
117 |
118 | .. versionadded:: 0.5
119 |
120 | :private:
121 | """
122 |
123 | def __reduce_ex__(self, protocol):
124 | return type(self), (list(self.items(multi=True)),)
125 |
126 | def _iter_hashitems(self):
127 | return self.items(multi=True)
128 |
129 | def add(self, key, value):
130 | is_immutable(self)
131 |
132 | def popitemlist(self):
133 | is_immutable(self)
134 |
135 | def poplist(self, key):
136 | is_immutable(self)
137 |
138 | def setlist(self, key, new_list):
139 | is_immutable(self)
140 |
141 | def setlistdefault(self, key, default_list=None):
142 | is_immutable(self)
143 |
144 |
145 | class ImmutableHeadersMixin:
146 | """Makes a :class:`Headers` immutable. We do not mark them as
147 | hashable though since the only usecase for this datastructure
148 | in Werkzeug is a view on a mutable structure.
149 |
150 | .. versionadded:: 0.5
151 |
152 | :private:
153 | """
154 |
155 | def __delitem__(self, key, **kwargs):
156 | is_immutable(self)
157 |
158 | def __setitem__(self, key, value):
159 | is_immutable(self)
160 |
161 | def set(self, _key, _value, **kwargs):
162 | is_immutable(self)
163 |
164 | def setlist(self, key, values):
165 | is_immutable(self)
166 |
167 | def add(self, _key, _value, **kwargs):
168 | is_immutable(self)
169 |
170 | def add_header(self, _key, _value, **_kwargs):
171 | is_immutable(self)
172 |
173 | def remove(self, key):
174 | is_immutable(self)
175 |
176 | def extend(self, *args, **kwargs):
177 | is_immutable(self)
178 |
179 | def update(self, *args, **kwargs):
180 | is_immutable(self)
181 |
182 | def insert(self, pos, value):
183 | is_immutable(self)
184 |
185 | def pop(self, key=None, default=_missing):
186 | is_immutable(self)
187 |
188 | def popitem(self):
189 | is_immutable(self)
190 |
191 | def setdefault(self, key, default):
192 | is_immutable(self)
193 |
194 | def setlistdefault(self, key, default):
195 | is_immutable(self)
196 |
197 |
198 | def _calls_update(name):
199 | def oncall(self, *args, **kw):
200 | rv = getattr(super(UpdateDictMixin, self), name)(*args, **kw)
201 |
202 | if self.on_update is not None:
203 | self.on_update(self)
204 |
205 | return rv
206 |
207 | oncall.__name__ = name
208 | return oncall
209 |
210 |
211 | class UpdateDictMixin(dict):
212 | """Makes dicts call `self.on_update` on modifications.
213 |
214 | .. versionadded:: 0.5
215 |
216 | :private:
217 | """
218 |
219 | on_update = None
220 |
221 | def setdefault(self, key, default=None):
222 | modified = key not in self
223 | rv = super().setdefault(key, default)
224 | if modified and self.on_update is not None:
225 | self.on_update(self)
226 | return rv
227 |
228 | def pop(self, key, default=_missing):
229 | modified = key in self
230 | if default is _missing:
231 | rv = super().pop(key)
232 | else:
233 | rv = super().pop(key, default)
234 | if modified and self.on_update is not None:
235 | self.on_update(self)
236 | return rv
237 |
238 | __setitem__ = _calls_update("__setitem__")
239 | __delitem__ = _calls_update("__delitem__")
240 | clear = _calls_update("clear")
241 | popitem = _calls_update("popitem")
242 | update = _calls_update("update")
243 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py:
--------------------------------------------------------------------------------
```python
1 | # -*- coding: utf-8 -*-
2 | """
3 | backports.weakref_finalize
4 | ~~~~~~~~~~~~~~~~~~
5 |
6 | Backports the Python 3 ``weakref.finalize`` method.
7 | """
8 | from __future__ import absolute_import
9 |
10 | import itertools
11 | import sys
12 | from weakref import ref
13 |
14 | __all__ = ["weakref_finalize"]
15 |
16 |
17 | class weakref_finalize(object):
18 | """Class for finalization of weakrefable objects
19 | finalize(obj, func, *args, **kwargs) returns a callable finalizer
20 | object which will be called when obj is garbage collected. The
21 | first time the finalizer is called it evaluates func(*arg, **kwargs)
22 | and returns the result. After this the finalizer is dead, and
23 | calling it just returns None.
24 | When the program exits any remaining finalizers for which the
25 | atexit attribute is true will be run in reverse order of creation.
26 | By default atexit is true.
27 | """
28 |
29 | # Finalizer objects don't have any state of their own. They are
30 | # just used as keys to lookup _Info objects in the registry. This
31 | # ensures that they cannot be part of a ref-cycle.
32 |
33 | __slots__ = ()
34 | _registry = {}
35 | _shutdown = False
36 | _index_iter = itertools.count()
37 | _dirty = False
38 | _registered_with_atexit = False
39 |
40 | class _Info(object):
41 | __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index")
42 |
43 | def __init__(self, obj, func, *args, **kwargs):
44 | if not self._registered_with_atexit:
45 | # We may register the exit function more than once because
46 | # of a thread race, but that is harmless
47 | import atexit
48 |
49 | atexit.register(self._exitfunc)
50 | weakref_finalize._registered_with_atexit = True
51 | info = self._Info()
52 | info.weakref = ref(obj, self)
53 | info.func = func
54 | info.args = args
55 | info.kwargs = kwargs or None
56 | info.atexit = True
57 | info.index = next(self._index_iter)
58 | self._registry[self] = info
59 | weakref_finalize._dirty = True
60 |
61 | def __call__(self, _=None):
62 | """If alive then mark as dead and return func(*args, **kwargs);
63 | otherwise return None"""
64 | info = self._registry.pop(self, None)
65 | if info and not self._shutdown:
66 | return info.func(*info.args, **(info.kwargs or {}))
67 |
68 | def detach(self):
69 | """If alive then mark as dead and return (obj, func, args, kwargs);
70 | otherwise return None"""
71 | info = self._registry.get(self)
72 | obj = info and info.weakref()
73 | if obj is not None and self._registry.pop(self, None):
74 | return (obj, info.func, info.args, info.kwargs or {})
75 |
76 | def peek(self):
77 | """If alive then return (obj, func, args, kwargs);
78 | otherwise return None"""
79 | info = self._registry.get(self)
80 | obj = info and info.weakref()
81 | if obj is not None:
82 | return (obj, info.func, info.args, info.kwargs or {})
83 |
84 | @property
85 | def alive(self):
86 | """Whether finalizer is alive"""
87 | return self in self._registry
88 |
89 | @property
90 | def atexit(self):
91 | """Whether finalizer should be called at exit"""
92 | info = self._registry.get(self)
93 | return bool(info) and info.atexit
94 |
95 | @atexit.setter
96 | def atexit(self, value):
97 | info = self._registry.get(self)
98 | if info:
99 | info.atexit = bool(value)
100 |
101 | def __repr__(self):
102 | info = self._registry.get(self)
103 | obj = info and info.weakref()
104 | if obj is None:
105 | return "<%s object at %#x; dead>" % (type(self).__name__, id(self))
106 | else:
107 | return "<%s object at %#x; for %r at %#x>" % (
108 | type(self).__name__,
109 | id(self),
110 | type(obj).__name__,
111 | id(obj),
112 | )
113 |
114 | @classmethod
115 | def _select_for_exit(cls):
116 | # Return live finalizers marked for exit, oldest first
117 | L = [(f, i) for (f, i) in cls._registry.items() if i.atexit]
118 | L.sort(key=lambda item: item[1].index)
119 | return [f for (f, i) in L]
120 |
121 | @classmethod
122 | def _exitfunc(cls):
123 | # At shutdown invoke finalizers for which atexit is true.
124 | # This is called once all other non-daemonic threads have been
125 | # joined.
126 | reenable_gc = False
127 | try:
128 | if cls._registry:
129 | import gc
130 |
131 | if gc.isenabled():
132 | reenable_gc = True
133 | gc.disable()
134 | pending = None
135 | while True:
136 | if pending is None or weakref_finalize._dirty:
137 | pending = cls._select_for_exit()
138 | weakref_finalize._dirty = False
139 | if not pending:
140 | break
141 | f = pending.pop()
142 | try:
143 | # gc is disabled, so (assuming no daemonic
144 | # threads) the following is the only line in
145 | # this function which might trigger creation
146 | # of a new finalizer
147 | f()
148 | except Exception:
149 | sys.excepthook(*sys.exc_info())
150 | assert f not in cls._registry
151 | finally:
152 | # prevent any more finalizers from executing during shutdown
153 | weakref_finalize._shutdown = True
154 | if reenable_gc:
155 | gc.enable()
156 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/sansio/http.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import re
4 | import typing as t
5 | from datetime import datetime
6 |
7 | from .._internal import _dt_as_utc
8 | from ..http import generate_etag
9 | from ..http import parse_date
10 | from ..http import parse_etags
11 | from ..http import parse_if_range_header
12 | from ..http import unquote_etag
13 |
14 | _etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)')
15 |
16 |
17 | def is_resource_modified(
18 | http_range: str | None = None,
19 | http_if_range: str | None = None,
20 | http_if_modified_since: str | None = None,
21 | http_if_none_match: str | None = None,
22 | http_if_match: str | None = None,
23 | etag: str | None = None,
24 | data: bytes | None = None,
25 | last_modified: datetime | str | None = None,
26 | ignore_if_range: bool = True,
27 | ) -> bool:
28 | """Convenience method for conditional requests.
29 | :param http_range: Range HTTP header
30 | :param http_if_range: If-Range HTTP header
31 | :param http_if_modified_since: If-Modified-Since HTTP header
32 | :param http_if_none_match: If-None-Match HTTP header
33 | :param http_if_match: If-Match HTTP header
34 | :param etag: the etag for the response for comparison.
35 | :param data: or alternatively the data of the response to automatically
36 | generate an etag using :func:`generate_etag`.
37 | :param last_modified: an optional date of the last modification.
38 | :param ignore_if_range: If `False`, `If-Range` header will be taken into
39 | account.
40 | :return: `True` if the resource was modified, otherwise `False`.
41 |
42 | .. versionadded:: 2.2
43 | """
44 | if etag is None and data is not None:
45 | etag = generate_etag(data)
46 | elif data is not None:
47 | raise TypeError("both data and etag given")
48 |
49 | unmodified = False
50 | if isinstance(last_modified, str):
51 | last_modified = parse_date(last_modified)
52 |
53 | # HTTP doesn't use microsecond, remove it to avoid false positive
54 | # comparisons. Mark naive datetimes as UTC.
55 | if last_modified is not None:
56 | last_modified = _dt_as_utc(last_modified.replace(microsecond=0))
57 |
58 | if_range = None
59 | if not ignore_if_range and http_range is not None:
60 | # https://tools.ietf.org/html/rfc7233#section-3.2
61 | # A server MUST ignore an If-Range header field received in a request
62 | # that does not contain a Range header field.
63 | if_range = parse_if_range_header(http_if_range)
64 |
65 | if if_range is not None and if_range.date is not None:
66 | modified_since: datetime | None = if_range.date
67 | else:
68 | modified_since = parse_date(http_if_modified_since)
69 |
70 | if modified_since and last_modified and last_modified <= modified_since:
71 | unmodified = True
72 |
73 | if etag:
74 | etag, _ = unquote_etag(etag)
75 | etag = t.cast(str, etag)
76 |
77 | if if_range is not None and if_range.etag is not None:
78 | unmodified = parse_etags(if_range.etag).contains(etag)
79 | else:
80 | if_none_match = parse_etags(http_if_none_match)
81 | if if_none_match:
82 | # https://tools.ietf.org/html/rfc7232#section-3.2
83 | # "A recipient MUST use the weak comparison function when comparing
84 | # entity-tags for If-None-Match"
85 | unmodified = if_none_match.contains_weak(etag)
86 |
87 | # https://tools.ietf.org/html/rfc7232#section-3.1
88 | # "Origin server MUST use the strong comparison function when
89 | # comparing entity-tags for If-Match"
90 | if_match = parse_etags(http_if_match)
91 | if if_match:
92 | unmodified = not if_match.is_strong(etag)
93 |
94 | return not unmodified
95 |
96 |
97 | _cookie_re = re.compile(
98 | r"""
99 | ([^=;]*)
100 | (?:\s*=\s*
101 | (
102 | "(?:[^\\"]|\\.)*"
103 | |
104 | .*?
105 | )
106 | )?
107 | \s*;\s*
108 | """,
109 | flags=re.ASCII | re.VERBOSE,
110 | )
111 | _cookie_unslash_re = re.compile(rb"\\([0-3][0-7]{2}|.)")
112 |
113 |
114 | def _cookie_unslash_replace(m: t.Match[bytes]) -> bytes:
115 | v = m.group(1)
116 |
117 | if len(v) == 1:
118 | return v
119 |
120 | return int(v, 8).to_bytes(1, "big")
121 |
122 |
123 | def parse_cookie(
124 | cookie: str | None = None,
125 | cls: type[ds.MultiDict[str, str]] | None = None,
126 | ) -> ds.MultiDict[str, str]:
127 | """Parse a cookie from a string.
128 |
129 | The same key can be provided multiple times, the values are stored
130 | in-order. The default :class:`MultiDict` will have the first value
131 | first, and all values can be retrieved with
132 | :meth:`MultiDict.getlist`.
133 |
134 | :param cookie: The cookie header as a string.
135 | :param cls: A dict-like class to store the parsed cookies in.
136 | Defaults to :class:`MultiDict`.
137 |
138 | .. versionchanged:: 3.0
139 | Passing bytes, and the ``charset`` and ``errors`` parameters, were removed.
140 |
141 | .. versionadded:: 2.2
142 | """
143 | if cls is None:
144 | cls = t.cast("type[ds.MultiDict[str, str]]", ds.MultiDict)
145 |
146 | if not cookie:
147 | return cls()
148 |
149 | cookie = f"{cookie};"
150 | out = []
151 |
152 | for ck, cv in _cookie_re.findall(cookie):
153 | ck = ck.strip()
154 | cv = cv.strip()
155 |
156 | if not ck:
157 | continue
158 |
159 | if len(cv) >= 2 and cv[0] == cv[-1] == '"':
160 | # Work with bytes here, since a UTF-8 character could be multiple bytes.
161 | cv = _cookie_unslash_re.sub(
162 | _cookie_unslash_replace, cv[1:-1].encode()
163 | ).decode(errors="replace")
164 |
165 | out.append((ck, cv))
166 |
167 | return cls(out)
168 |
169 |
170 | # circular dependencies
171 | from .. import datastructures as ds
172 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/security.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import hashlib
4 | import hmac
5 | import os
6 | import posixpath
7 | import secrets
8 |
9 | SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
10 | DEFAULT_PBKDF2_ITERATIONS = 600000
11 |
12 | _os_alt_seps: list[str] = list(
13 | sep for sep in [os.sep, os.path.altsep] if sep is not None and sep != "/"
14 | )
15 |
16 |
17 | def gen_salt(length: int) -> str:
18 | """Generate a random string of SALT_CHARS with specified ``length``."""
19 | if length <= 0:
20 | raise ValueError("Salt length must be at least 1.")
21 |
22 | return "".join(secrets.choice(SALT_CHARS) for _ in range(length))
23 |
24 |
25 | def _hash_internal(method: str, salt: str, password: str) -> tuple[str, str]:
26 | method, *args = method.split(":")
27 | salt_bytes = salt.encode()
28 | password_bytes = password.encode()
29 |
30 | if method == "scrypt":
31 | if not args:
32 | n = 2**15
33 | r = 8
34 | p = 1
35 | else:
36 | try:
37 | n, r, p = map(int, args)
38 | except ValueError:
39 | raise ValueError("'scrypt' takes 3 arguments.") from None
40 |
41 | maxmem = 132 * n * r * p # ideally 128, but some extra seems needed
42 | return (
43 | hashlib.scrypt(
44 | password_bytes, salt=salt_bytes, n=n, r=r, p=p, maxmem=maxmem
45 | ).hex(),
46 | f"scrypt:{n}:{r}:{p}",
47 | )
48 | elif method == "pbkdf2":
49 | len_args = len(args)
50 |
51 | if len_args == 0:
52 | hash_name = "sha256"
53 | iterations = DEFAULT_PBKDF2_ITERATIONS
54 | elif len_args == 1:
55 | hash_name = args[0]
56 | iterations = DEFAULT_PBKDF2_ITERATIONS
57 | elif len_args == 2:
58 | hash_name = args[0]
59 | iterations = int(args[1])
60 | else:
61 | raise ValueError("'pbkdf2' takes 2 arguments.")
62 |
63 | return (
64 | hashlib.pbkdf2_hmac(
65 | hash_name, password_bytes, salt_bytes, iterations
66 | ).hex(),
67 | f"pbkdf2:{hash_name}:{iterations}",
68 | )
69 | else:
70 | raise ValueError(f"Invalid hash method '{method}'.")
71 |
72 |
73 | def generate_password_hash(
74 | password: str, method: str = "scrypt", salt_length: int = 16
75 | ) -> str:
76 | """Securely hash a password for storage. A password can be compared to a stored hash
77 | using :func:`check_password_hash`.
78 |
79 | The following methods are supported:
80 |
81 | - ``scrypt``, the default. The parameters are ``n``, ``r``, and ``p``, the default
82 | is ``scrypt:32768:8:1``. See :func:`hashlib.scrypt`.
83 | - ``pbkdf2``, less secure. The parameters are ``hash_method`` and ``iterations``,
84 | the default is ``pbkdf2:sha256:600000``. See :func:`hashlib.pbkdf2_hmac`.
85 |
86 | Default parameters may be updated to reflect current guidelines, and methods may be
87 | deprecated and removed if they are no longer considered secure. To migrate old
88 | hashes, you may generate a new hash when checking an old hash, or you may contact
89 | users with a link to reset their password.
90 |
91 | :param password: The plaintext password.
92 | :param method: The key derivation function and parameters.
93 | :param salt_length: The number of characters to generate for the salt.
94 |
95 | .. versionchanged:: 2.3
96 | Scrypt support was added.
97 |
98 | .. versionchanged:: 2.3
99 | The default iterations for pbkdf2 was increased to 600,000.
100 |
101 | .. versionchanged:: 2.3
102 | All plain hashes are deprecated and will not be supported in Werkzeug 3.0.
103 | """
104 | salt = gen_salt(salt_length)
105 | h, actual_method = _hash_internal(method, salt, password)
106 | return f"{actual_method}${salt}${h}"
107 |
108 |
109 | def check_password_hash(pwhash: str, password: str) -> bool:
110 | """Securely check that the given stored password hash, previously generated using
111 | :func:`generate_password_hash`, matches the given password.
112 |
113 | Methods may be deprecated and removed if they are no longer considered secure. To
114 | migrate old hashes, you may generate a new hash when checking an old hash, or you
115 | may contact users with a link to reset their password.
116 |
117 | :param pwhash: The hashed password.
118 | :param password: The plaintext password.
119 |
120 | .. versionchanged:: 2.3
121 | All plain hashes are deprecated and will not be supported in Werkzeug 3.0.
122 | """
123 | try:
124 | method, salt, hashval = pwhash.split("$", 2)
125 | except ValueError:
126 | return False
127 |
128 | return hmac.compare_digest(_hash_internal(method, salt, password)[0], hashval)
129 |
130 |
131 | def safe_join(directory: str, *pathnames: str) -> str | None:
132 | """Safely join zero or more untrusted path components to a base
133 | directory to avoid escaping the base directory.
134 |
135 | :param directory: The trusted base directory.
136 | :param pathnames: The untrusted path components relative to the
137 | base directory.
138 | :return: A safe path, otherwise ``None``.
139 | """
140 | if not directory:
141 | # Ensure we end up with ./path if directory="" is given,
142 | # otherwise the first untrusted part could become trusted.
143 | directory = "."
144 |
145 | parts = [directory]
146 |
147 | for filename in pathnames:
148 | if filename != "":
149 | filename = posixpath.normpath(filename)
150 |
151 | if (
152 | any(sep in filename for sep in _os_alt_seps)
153 | or os.path.isabs(filename)
154 | or filename == ".."
155 | or filename.startswith("../")
156 | ):
157 | return None
158 |
159 | parts.append(filename)
160 |
161 | return posixpath.join(*parts)
162 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/utils/compatibility_tags.py:
--------------------------------------------------------------------------------
```python
1 | """Generate and work with PEP 425 Compatibility Tags.
2 | """
3 |
4 | import re
5 | from typing import List, Optional, Tuple
6 |
7 | from pip._vendor.packaging.tags import (
8 | PythonVersion,
9 | Tag,
10 | compatible_tags,
11 | cpython_tags,
12 | generic_tags,
13 | interpreter_name,
14 | interpreter_version,
15 | mac_platforms,
16 | )
17 |
18 | _osx_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)")
19 |
20 |
21 | def version_info_to_nodot(version_info: Tuple[int, ...]) -> str:
22 | # Only use up to the first two numbers.
23 | return "".join(map(str, version_info[:2]))
24 |
25 |
26 | def _mac_platforms(arch: str) -> List[str]:
27 | match = _osx_arch_pat.match(arch)
28 | if match:
29 | name, major, minor, actual_arch = match.groups()
30 | mac_version = (int(major), int(minor))
31 | arches = [
32 | # Since we have always only checked that the platform starts
33 | # with "macosx", for backwards-compatibility we extract the
34 | # actual prefix provided by the user in case they provided
35 | # something like "macosxcustom_". It may be good to remove
36 | # this as undocumented or deprecate it in the future.
37 | "{}_{}".format(name, arch[len("macosx_") :])
38 | for arch in mac_platforms(mac_version, actual_arch)
39 | ]
40 | else:
41 | # arch pattern didn't match (?!)
42 | arches = [arch]
43 | return arches
44 |
45 |
46 | def _custom_manylinux_platforms(arch: str) -> List[str]:
47 | arches = [arch]
48 | arch_prefix, arch_sep, arch_suffix = arch.partition("_")
49 | if arch_prefix == "manylinux2014":
50 | # manylinux1/manylinux2010 wheels run on most manylinux2014 systems
51 | # with the exception of wheels depending on ncurses. PEP 599 states
52 | # manylinux1/manylinux2010 wheels should be considered
53 | # manylinux2014 wheels:
54 | # https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels
55 | if arch_suffix in {"i686", "x86_64"}:
56 | arches.append("manylinux2010" + arch_sep + arch_suffix)
57 | arches.append("manylinux1" + arch_sep + arch_suffix)
58 | elif arch_prefix == "manylinux2010":
59 | # manylinux1 wheels run on most manylinux2010 systems with the
60 | # exception of wheels depending on ncurses. PEP 571 states
61 | # manylinux1 wheels should be considered manylinux2010 wheels:
62 | # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels
63 | arches.append("manylinux1" + arch_sep + arch_suffix)
64 | return arches
65 |
66 |
67 | def _get_custom_platforms(arch: str) -> List[str]:
68 | arch_prefix, arch_sep, arch_suffix = arch.partition("_")
69 | if arch.startswith("macosx"):
70 | arches = _mac_platforms(arch)
71 | elif arch_prefix in ["manylinux2014", "manylinux2010"]:
72 | arches = _custom_manylinux_platforms(arch)
73 | else:
74 | arches = [arch]
75 | return arches
76 |
77 |
78 | def _expand_allowed_platforms(platforms: Optional[List[str]]) -> Optional[List[str]]:
79 | if not platforms:
80 | return None
81 |
82 | seen = set()
83 | result = []
84 |
85 | for p in platforms:
86 | if p in seen:
87 | continue
88 | additions = [c for c in _get_custom_platforms(p) if c not in seen]
89 | seen.update(additions)
90 | result.extend(additions)
91 |
92 | return result
93 |
94 |
95 | def _get_python_version(version: str) -> PythonVersion:
96 | if len(version) > 1:
97 | return int(version[0]), int(version[1:])
98 | else:
99 | return (int(version[0]),)
100 |
101 |
102 | def _get_custom_interpreter(
103 | implementation: Optional[str] = None, version: Optional[str] = None
104 | ) -> str:
105 | if implementation is None:
106 | implementation = interpreter_name()
107 | if version is None:
108 | version = interpreter_version()
109 | return f"{implementation}{version}"
110 |
111 |
112 | def get_supported(
113 | version: Optional[str] = None,
114 | platforms: Optional[List[str]] = None,
115 | impl: Optional[str] = None,
116 | abis: Optional[List[str]] = None,
117 | ) -> List[Tag]:
118 | """Return a list of supported tags for each version specified in
119 | `versions`.
120 |
121 | :param version: a string version, of the form "33" or "32",
122 | or None. The version will be assumed to support our ABI.
123 | :param platform: specify a list of platforms you want valid
124 | tags for, or None. If None, use the local system platform.
125 | :param impl: specify the exact implementation you want valid
126 | tags for, or None. If None, use the local interpreter impl.
127 | :param abis: specify a list of abis you want valid
128 | tags for, or None. If None, use the local interpreter abi.
129 | """
130 | supported: List[Tag] = []
131 |
132 | python_version: Optional[PythonVersion] = None
133 | if version is not None:
134 | python_version = _get_python_version(version)
135 |
136 | interpreter = _get_custom_interpreter(impl, version)
137 |
138 | platforms = _expand_allowed_platforms(platforms)
139 |
140 | is_cpython = (impl or interpreter_name()) == "cp"
141 | if is_cpython:
142 | supported.extend(
143 | cpython_tags(
144 | python_version=python_version,
145 | abis=abis,
146 | platforms=platforms,
147 | )
148 | )
149 | else:
150 | supported.extend(
151 | generic_tags(
152 | interpreter=interpreter,
153 | abis=abis,
154 | platforms=platforms,
155 | )
156 | )
157 | supported.extend(
158 | compatible_tags(
159 | python_version=python_version,
160 | interpreter=interpreter,
161 | platforms=platforms,
162 | )
163 | )
164 |
165 | return supported
166 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__init__.py:
--------------------------------------------------------------------------------
```python
1 | """
2 | pygments.formatters
3 | ~~~~~~~~~~~~~~~~~~~
4 |
5 | Pygments formatters.
6 |
7 | :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS.
8 | :license: BSD, see LICENSE for details.
9 | """
10 |
11 | import re
12 | import sys
13 | import types
14 | import fnmatch
15 | from os.path import basename
16 |
17 | from pip._vendor.pygments.formatters._mapping import FORMATTERS
18 | from pip._vendor.pygments.plugin import find_plugin_formatters
19 | from pip._vendor.pygments.util import ClassNotFound
20 |
21 | __all__ = ['get_formatter_by_name', 'get_formatter_for_filename',
22 | 'get_all_formatters', 'load_formatter_from_file'] + list(FORMATTERS)
23 |
24 | _formatter_cache = {} # classes by name
25 | _pattern_cache = {}
26 |
27 |
28 | def _fn_matches(fn, glob):
29 | """Return whether the supplied file name fn matches pattern filename."""
30 | if glob not in _pattern_cache:
31 | pattern = _pattern_cache[glob] = re.compile(fnmatch.translate(glob))
32 | return pattern.match(fn)
33 | return _pattern_cache[glob].match(fn)
34 |
35 |
36 | def _load_formatters(module_name):
37 | """Load a formatter (and all others in the module too)."""
38 | mod = __import__(module_name, None, None, ['__all__'])
39 | for formatter_name in mod.__all__:
40 | cls = getattr(mod, formatter_name)
41 | _formatter_cache[cls.name] = cls
42 |
43 |
44 | def get_all_formatters():
45 | """Return a generator for all formatter classes."""
46 | # NB: this returns formatter classes, not info like get_all_lexers().
47 | for info in FORMATTERS.values():
48 | if info[1] not in _formatter_cache:
49 | _load_formatters(info[0])
50 | yield _formatter_cache[info[1]]
51 | for _, formatter in find_plugin_formatters():
52 | yield formatter
53 |
54 |
55 | def find_formatter_class(alias):
56 | """Lookup a formatter by alias.
57 |
58 | Returns None if not found.
59 | """
60 | for module_name, name, aliases, _, _ in FORMATTERS.values():
61 | if alias in aliases:
62 | if name not in _formatter_cache:
63 | _load_formatters(module_name)
64 | return _formatter_cache[name]
65 | for _, cls in find_plugin_formatters():
66 | if alias in cls.aliases:
67 | return cls
68 |
69 |
70 | def get_formatter_by_name(_alias, **options):
71 | """
72 | Return an instance of a :class:`.Formatter` subclass that has `alias` in its
73 | aliases list. The formatter is given the `options` at its instantiation.
74 |
75 | Will raise :exc:`pygments.util.ClassNotFound` if no formatter with that
76 | alias is found.
77 | """
78 | cls = find_formatter_class(_alias)
79 | if cls is None:
80 | raise ClassNotFound(f"no formatter found for name {_alias!r}")
81 | return cls(**options)
82 |
83 |
84 | def load_formatter_from_file(filename, formattername="CustomFormatter", **options):
85 | """
86 | Return a `Formatter` subclass instance loaded from the provided file, relative
87 | to the current directory.
88 |
89 | The file is expected to contain a Formatter class named ``formattername``
90 | (by default, CustomFormatter). Users should be very careful with the input, because
91 | this method is equivalent to running ``eval()`` on the input file. The formatter is
92 | given the `options` at its instantiation.
93 |
94 | :exc:`pygments.util.ClassNotFound` is raised if there are any errors loading
95 | the formatter.
96 |
97 | .. versionadded:: 2.2
98 | """
99 | try:
100 | # This empty dict will contain the namespace for the exec'd file
101 | custom_namespace = {}
102 | with open(filename, 'rb') as f:
103 | exec(f.read(), custom_namespace)
104 | # Retrieve the class `formattername` from that namespace
105 | if formattername not in custom_namespace:
106 | raise ClassNotFound(f'no valid {formattername} class found in {filename}')
107 | formatter_class = custom_namespace[formattername]
108 | # And finally instantiate it with the options
109 | return formatter_class(**options)
110 | except OSError as err:
111 | raise ClassNotFound(f'cannot read {filename}: {err}')
112 | except ClassNotFound:
113 | raise
114 | except Exception as err:
115 | raise ClassNotFound(f'error when loading custom formatter: {err}')
116 |
117 |
118 | def get_formatter_for_filename(fn, **options):
119 | """
120 | Return a :class:`.Formatter` subclass instance that has a filename pattern
121 | matching `fn`. The formatter is given the `options` at its instantiation.
122 |
123 | Will raise :exc:`pygments.util.ClassNotFound` if no formatter for that filename
124 | is found.
125 | """
126 | fn = basename(fn)
127 | for modname, name, _, filenames, _ in FORMATTERS.values():
128 | for filename in filenames:
129 | if _fn_matches(fn, filename):
130 | if name not in _formatter_cache:
131 | _load_formatters(modname)
132 | return _formatter_cache[name](**options)
133 | for _name, cls in find_plugin_formatters():
134 | for filename in cls.filenames:
135 | if _fn_matches(fn, filename):
136 | return cls(**options)
137 | raise ClassNotFound(f"no formatter found for file name {fn!r}")
138 |
139 |
140 | class _automodule(types.ModuleType):
141 | """Automatically import formatters."""
142 |
143 | def __getattr__(self, name):
144 | info = FORMATTERS.get(name)
145 | if info:
146 | _load_formatters(info[0])
147 | cls = _formatter_cache[info[1]]
148 | setattr(self, name, cls)
149 | return cls
150 | raise AttributeError(name)
151 |
152 |
153 | oldmod = sys.modules[__name__]
154 | newmod = _automodule(__name__)
155 | newmod.__dict__.update(oldmod.__dict__)
156 | sys.modules[__name__] = newmod
157 | del newmod.newmod, newmod.oldmod, newmod.sys, newmod.types
158 |
```