This is page 73 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/_vendor/platformdirs/__init__.py:
--------------------------------------------------------------------------------
```python
1 | """
2 | Utilities for determining application-specific dirs.
3 |
4 | See <https://github.com/platformdirs/platformdirs> for details and usage.
5 |
6 | """
7 |
8 | from __future__ import annotations
9 |
10 | import os
11 | import sys
12 | from typing import TYPE_CHECKING
13 |
14 | from .api import PlatformDirsABC
15 | from .version import __version__
16 | from .version import __version_tuple__ as __version_info__
17 |
18 | if TYPE_CHECKING:
19 | from pathlib import Path
20 | from typing import Literal
21 |
22 |
23 | def _set_platform_dir_class() -> type[PlatformDirsABC]:
24 | if sys.platform == "win32":
25 | from pip._vendor.platformdirs.windows import Windows as Result # noqa: PLC0415
26 | elif sys.platform == "darwin":
27 | from pip._vendor.platformdirs.macos import MacOS as Result # noqa: PLC0415
28 | else:
29 | from pip._vendor.platformdirs.unix import Unix as Result # noqa: PLC0415
30 |
31 | if os.getenv("ANDROID_DATA") == "/data" and os.getenv("ANDROID_ROOT") == "/system":
32 | if os.getenv("SHELL") or os.getenv("PREFIX"):
33 | return Result
34 |
35 | from pip._vendor.platformdirs.android import _android_folder # noqa: PLC0415
36 |
37 | if _android_folder() is not None:
38 | from pip._vendor.platformdirs.android import Android # noqa: PLC0415
39 |
40 | return Android # return to avoid redefinition of a result
41 |
42 | return Result
43 |
44 |
45 | PlatformDirs = _set_platform_dir_class() #: Currently active platform
46 | AppDirs = PlatformDirs #: Backwards compatibility with appdirs
47 |
48 |
49 | def user_data_dir(
50 | appname: str | None = None,
51 | appauthor: str | None | Literal[False] = None,
52 | version: str | None = None,
53 | roaming: bool = False, # noqa: FBT001, FBT002
54 | ensure_exists: bool = False, # noqa: FBT001, FBT002
55 | ) -> str:
56 | """
57 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
58 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
59 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
60 | :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
61 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
62 | :returns: data directory tied to the user
63 | """
64 | return PlatformDirs(
65 | appname=appname,
66 | appauthor=appauthor,
67 | version=version,
68 | roaming=roaming,
69 | ensure_exists=ensure_exists,
70 | ).user_data_dir
71 |
72 |
73 | def site_data_dir(
74 | appname: str | None = None,
75 | appauthor: str | None | Literal[False] = None,
76 | version: str | None = None,
77 | multipath: bool = False, # noqa: FBT001, FBT002
78 | ensure_exists: bool = False, # noqa: FBT001, FBT002
79 | ) -> str:
80 | """
81 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
82 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
83 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
84 | :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
85 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
86 | :returns: data directory shared by users
87 | """
88 | return PlatformDirs(
89 | appname=appname,
90 | appauthor=appauthor,
91 | version=version,
92 | multipath=multipath,
93 | ensure_exists=ensure_exists,
94 | ).site_data_dir
95 |
96 |
97 | def user_config_dir(
98 | appname: str | None = None,
99 | appauthor: str | None | Literal[False] = None,
100 | version: str | None = None,
101 | roaming: bool = False, # noqa: FBT001, FBT002
102 | ensure_exists: bool = False, # noqa: FBT001, FBT002
103 | ) -> str:
104 | """
105 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
106 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
107 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
108 | :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
109 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
110 | :returns: config directory tied to the user
111 | """
112 | return PlatformDirs(
113 | appname=appname,
114 | appauthor=appauthor,
115 | version=version,
116 | roaming=roaming,
117 | ensure_exists=ensure_exists,
118 | ).user_config_dir
119 |
120 |
121 | def site_config_dir(
122 | appname: str | None = None,
123 | appauthor: str | None | Literal[False] = None,
124 | version: str | None = None,
125 | multipath: bool = False, # noqa: FBT001, FBT002
126 | ensure_exists: bool = False, # noqa: FBT001, FBT002
127 | ) -> str:
128 | """
129 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
130 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
131 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
132 | :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
133 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
134 | :returns: config directory shared by the users
135 | """
136 | return PlatformDirs(
137 | appname=appname,
138 | appauthor=appauthor,
139 | version=version,
140 | multipath=multipath,
141 | ensure_exists=ensure_exists,
142 | ).site_config_dir
143 |
144 |
145 | def user_cache_dir(
146 | appname: str | None = None,
147 | appauthor: str | None | Literal[False] = None,
148 | version: str | None = None,
149 | opinion: bool = True, # noqa: FBT001, FBT002
150 | ensure_exists: bool = False, # noqa: FBT001, FBT002
151 | ) -> str:
152 | """
153 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
154 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
155 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
156 | :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
157 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
158 | :returns: cache directory tied to the user
159 | """
160 | return PlatformDirs(
161 | appname=appname,
162 | appauthor=appauthor,
163 | version=version,
164 | opinion=opinion,
165 | ensure_exists=ensure_exists,
166 | ).user_cache_dir
167 |
168 |
169 | def site_cache_dir(
170 | appname: str | None = None,
171 | appauthor: str | None | Literal[False] = None,
172 | version: str | None = None,
173 | opinion: bool = True, # noqa: FBT001, FBT002
174 | ensure_exists: bool = False, # noqa: FBT001, FBT002
175 | ) -> str:
176 | """
177 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
178 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
179 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
180 | :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
181 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
182 | :returns: cache directory tied to the user
183 | """
184 | return PlatformDirs(
185 | appname=appname,
186 | appauthor=appauthor,
187 | version=version,
188 | opinion=opinion,
189 | ensure_exists=ensure_exists,
190 | ).site_cache_dir
191 |
192 |
193 | def user_state_dir(
194 | appname: str | None = None,
195 | appauthor: str | None | Literal[False] = None,
196 | version: str | None = None,
197 | roaming: bool = False, # noqa: FBT001, FBT002
198 | ensure_exists: bool = False, # noqa: FBT001, FBT002
199 | ) -> str:
200 | """
201 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
202 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
203 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
204 | :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
205 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
206 | :returns: state directory tied to the user
207 | """
208 | return PlatformDirs(
209 | appname=appname,
210 | appauthor=appauthor,
211 | version=version,
212 | roaming=roaming,
213 | ensure_exists=ensure_exists,
214 | ).user_state_dir
215 |
216 |
217 | def user_log_dir(
218 | appname: str | None = None,
219 | appauthor: str | None | Literal[False] = None,
220 | version: str | None = None,
221 | opinion: bool = True, # noqa: FBT001, FBT002
222 | ensure_exists: bool = False, # noqa: FBT001, FBT002
223 | ) -> str:
224 | """
225 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
226 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
227 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
228 | :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
229 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
230 | :returns: log directory tied to the user
231 | """
232 | return PlatformDirs(
233 | appname=appname,
234 | appauthor=appauthor,
235 | version=version,
236 | opinion=opinion,
237 | ensure_exists=ensure_exists,
238 | ).user_log_dir
239 |
240 |
241 | def user_documents_dir() -> str:
242 | """:returns: documents directory tied to the user"""
243 | return PlatformDirs().user_documents_dir
244 |
245 |
246 | def user_downloads_dir() -> str:
247 | """:returns: downloads directory tied to the user"""
248 | return PlatformDirs().user_downloads_dir
249 |
250 |
251 | def user_pictures_dir() -> str:
252 | """:returns: pictures directory tied to the user"""
253 | return PlatformDirs().user_pictures_dir
254 |
255 |
256 | def user_videos_dir() -> str:
257 | """:returns: videos directory tied to the user"""
258 | return PlatformDirs().user_videos_dir
259 |
260 |
261 | def user_music_dir() -> str:
262 | """:returns: music directory tied to the user"""
263 | return PlatformDirs().user_music_dir
264 |
265 |
266 | def user_desktop_dir() -> str:
267 | """:returns: desktop directory tied to the user"""
268 | return PlatformDirs().user_desktop_dir
269 |
270 |
271 | def user_runtime_dir(
272 | appname: str | None = None,
273 | appauthor: str | None | Literal[False] = None,
274 | version: str | None = None,
275 | opinion: bool = True, # noqa: FBT001, FBT002
276 | ensure_exists: bool = False, # noqa: FBT001, FBT002
277 | ) -> str:
278 | """
279 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
280 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
281 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
282 | :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
283 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
284 | :returns: runtime directory tied to the user
285 | """
286 | return PlatformDirs(
287 | appname=appname,
288 | appauthor=appauthor,
289 | version=version,
290 | opinion=opinion,
291 | ensure_exists=ensure_exists,
292 | ).user_runtime_dir
293 |
294 |
295 | def site_runtime_dir(
296 | appname: str | None = None,
297 | appauthor: str | None | Literal[False] = None,
298 | version: str | None = None,
299 | opinion: bool = True, # noqa: FBT001, FBT002
300 | ensure_exists: bool = False, # noqa: FBT001, FBT002
301 | ) -> str:
302 | """
303 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
304 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
305 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
306 | :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
307 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
308 | :returns: runtime directory shared by users
309 | """
310 | return PlatformDirs(
311 | appname=appname,
312 | appauthor=appauthor,
313 | version=version,
314 | opinion=opinion,
315 | ensure_exists=ensure_exists,
316 | ).site_runtime_dir
317 |
318 |
319 | def user_data_path(
320 | appname: str | None = None,
321 | appauthor: str | None | Literal[False] = None,
322 | version: str | None = None,
323 | roaming: bool = False, # noqa: FBT001, FBT002
324 | ensure_exists: bool = False, # noqa: FBT001, FBT002
325 | ) -> Path:
326 | """
327 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
328 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
329 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
330 | :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
331 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
332 | :returns: data path tied to the user
333 | """
334 | return PlatformDirs(
335 | appname=appname,
336 | appauthor=appauthor,
337 | version=version,
338 | roaming=roaming,
339 | ensure_exists=ensure_exists,
340 | ).user_data_path
341 |
342 |
343 | def site_data_path(
344 | appname: str | None = None,
345 | appauthor: str | None | Literal[False] = None,
346 | version: str | None = None,
347 | multipath: bool = False, # noqa: FBT001, FBT002
348 | ensure_exists: bool = False, # noqa: FBT001, FBT002
349 | ) -> Path:
350 | """
351 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
352 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
353 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
354 | :param multipath: See `multipath <platformdirs.api.PlatformDirsABC.multipath>`.
355 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
356 | :returns: data path shared by users
357 | """
358 | return PlatformDirs(
359 | appname=appname,
360 | appauthor=appauthor,
361 | version=version,
362 | multipath=multipath,
363 | ensure_exists=ensure_exists,
364 | ).site_data_path
365 |
366 |
367 | def user_config_path(
368 | appname: str | None = None,
369 | appauthor: str | None | Literal[False] = None,
370 | version: str | None = None,
371 | roaming: bool = False, # noqa: FBT001, FBT002
372 | ensure_exists: bool = False, # noqa: FBT001, FBT002
373 | ) -> Path:
374 | """
375 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
376 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
377 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
378 | :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
379 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
380 | :returns: config path tied to the user
381 | """
382 | return PlatformDirs(
383 | appname=appname,
384 | appauthor=appauthor,
385 | version=version,
386 | roaming=roaming,
387 | ensure_exists=ensure_exists,
388 | ).user_config_path
389 |
390 |
391 | def site_config_path(
392 | appname: str | None = None,
393 | appauthor: str | None | Literal[False] = None,
394 | version: str | None = None,
395 | multipath: bool = False, # noqa: FBT001, FBT002
396 | ensure_exists: bool = False, # noqa: FBT001, FBT002
397 | ) -> Path:
398 | """
399 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
400 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
401 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
402 | :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
403 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
404 | :returns: config path shared by the users
405 | """
406 | return PlatformDirs(
407 | appname=appname,
408 | appauthor=appauthor,
409 | version=version,
410 | multipath=multipath,
411 | ensure_exists=ensure_exists,
412 | ).site_config_path
413 |
414 |
415 | def site_cache_path(
416 | appname: str | None = None,
417 | appauthor: str | None | Literal[False] = None,
418 | version: str | None = None,
419 | opinion: bool = True, # noqa: FBT001, FBT002
420 | ensure_exists: bool = False, # noqa: FBT001, FBT002
421 | ) -> Path:
422 | """
423 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
424 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
425 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
426 | :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
427 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
428 | :returns: cache directory tied to the user
429 | """
430 | return PlatformDirs(
431 | appname=appname,
432 | appauthor=appauthor,
433 | version=version,
434 | opinion=opinion,
435 | ensure_exists=ensure_exists,
436 | ).site_cache_path
437 |
438 |
439 | def user_cache_path(
440 | appname: str | None = None,
441 | appauthor: str | None | Literal[False] = None,
442 | version: str | None = None,
443 | opinion: bool = True, # noqa: FBT001, FBT002
444 | ensure_exists: bool = False, # noqa: FBT001, FBT002
445 | ) -> Path:
446 | """
447 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
448 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
449 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
450 | :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
451 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
452 | :returns: cache path tied to the user
453 | """
454 | return PlatformDirs(
455 | appname=appname,
456 | appauthor=appauthor,
457 | version=version,
458 | opinion=opinion,
459 | ensure_exists=ensure_exists,
460 | ).user_cache_path
461 |
462 |
463 | def user_state_path(
464 | appname: str | None = None,
465 | appauthor: str | None | Literal[False] = None,
466 | version: str | None = None,
467 | roaming: bool = False, # noqa: FBT001, FBT002
468 | ensure_exists: bool = False, # noqa: FBT001, FBT002
469 | ) -> Path:
470 | """
471 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
472 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
473 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
474 | :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
475 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
476 | :returns: state path tied to the user
477 | """
478 | return PlatformDirs(
479 | appname=appname,
480 | appauthor=appauthor,
481 | version=version,
482 | roaming=roaming,
483 | ensure_exists=ensure_exists,
484 | ).user_state_path
485 |
486 |
487 | def user_log_path(
488 | appname: str | None = None,
489 | appauthor: str | None | Literal[False] = None,
490 | version: str | None = None,
491 | opinion: bool = True, # noqa: FBT001, FBT002
492 | ensure_exists: bool = False, # noqa: FBT001, FBT002
493 | ) -> Path:
494 | """
495 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
496 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
497 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
498 | :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
499 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
500 | :returns: log path tied to the user
501 | """
502 | return PlatformDirs(
503 | appname=appname,
504 | appauthor=appauthor,
505 | version=version,
506 | opinion=opinion,
507 | ensure_exists=ensure_exists,
508 | ).user_log_path
509 |
510 |
511 | def user_documents_path() -> Path:
512 | """:returns: documents a path tied to the user"""
513 | return PlatformDirs().user_documents_path
514 |
515 |
516 | def user_downloads_path() -> Path:
517 | """:returns: downloads path tied to the user"""
518 | return PlatformDirs().user_downloads_path
519 |
520 |
521 | def user_pictures_path() -> Path:
522 | """:returns: pictures path tied to the user"""
523 | return PlatformDirs().user_pictures_path
524 |
525 |
526 | def user_videos_path() -> Path:
527 | """:returns: videos path tied to the user"""
528 | return PlatformDirs().user_videos_path
529 |
530 |
531 | def user_music_path() -> Path:
532 | """:returns: music path tied to the user"""
533 | return PlatformDirs().user_music_path
534 |
535 |
536 | def user_desktop_path() -> Path:
537 | """:returns: desktop path tied to the user"""
538 | return PlatformDirs().user_desktop_path
539 |
540 |
541 | def user_runtime_path(
542 | appname: str | None = None,
543 | appauthor: str | None | Literal[False] = None,
544 | version: str | None = None,
545 | opinion: bool = True, # noqa: FBT001, FBT002
546 | ensure_exists: bool = False, # noqa: FBT001, FBT002
547 | ) -> Path:
548 | """
549 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
550 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
551 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
552 | :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
553 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
554 | :returns: runtime path tied to the user
555 | """
556 | return PlatformDirs(
557 | appname=appname,
558 | appauthor=appauthor,
559 | version=version,
560 | opinion=opinion,
561 | ensure_exists=ensure_exists,
562 | ).user_runtime_path
563 |
564 |
565 | def site_runtime_path(
566 | appname: str | None = None,
567 | appauthor: str | None | Literal[False] = None,
568 | version: str | None = None,
569 | opinion: bool = True, # noqa: FBT001, FBT002
570 | ensure_exists: bool = False, # noqa: FBT001, FBT002
571 | ) -> Path:
572 | """
573 | :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
574 | :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
575 | :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
576 | :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
577 | :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
578 | :returns: runtime path shared by users
579 | """
580 | return PlatformDirs(
581 | appname=appname,
582 | appauthor=appauthor,
583 | version=version,
584 | opinion=opinion,
585 | ensure_exists=ensure_exists,
586 | ).site_runtime_path
587 |
588 |
589 | __all__ = [
590 | "AppDirs",
591 | "PlatformDirs",
592 | "PlatformDirsABC",
593 | "__version__",
594 | "__version_info__",
595 | "site_cache_dir",
596 | "site_cache_path",
597 | "site_config_dir",
598 | "site_config_path",
599 | "site_data_dir",
600 | "site_data_path",
601 | "site_runtime_dir",
602 | "site_runtime_path",
603 | "user_cache_dir",
604 | "user_cache_path",
605 | "user_config_dir",
606 | "user_config_path",
607 | "user_data_dir",
608 | "user_data_path",
609 | "user_desktop_dir",
610 | "user_desktop_path",
611 | "user_documents_dir",
612 | "user_documents_path",
613 | "user_downloads_dir",
614 | "user_downloads_path",
615 | "user_log_dir",
616 | "user_log_path",
617 | "user_music_dir",
618 | "user_music_path",
619 | "user_pictures_dir",
620 | "user_pictures_path",
621 | "user_runtime_dir",
622 | "user_runtime_path",
623 | "user_state_dir",
624 | "user_state_path",
625 | "user_videos_dir",
626 | "user_videos_path",
627 | ]
628 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/vcs/versioncontrol.py:
--------------------------------------------------------------------------------
```python
1 | """Handles all VCS (version control) support"""
2 |
3 | import logging
4 | import os
5 | import shutil
6 | import sys
7 | import urllib.parse
8 | from dataclasses import dataclass, field
9 | from typing import (
10 | Any,
11 | Dict,
12 | Iterable,
13 | Iterator,
14 | List,
15 | Literal,
16 | Mapping,
17 | Optional,
18 | Tuple,
19 | Type,
20 | Union,
21 | )
22 |
23 | from pip._internal.cli.spinners import SpinnerInterface
24 | from pip._internal.exceptions import BadCommand, InstallationError
25 | from pip._internal.utils.misc import (
26 | HiddenText,
27 | ask_path_exists,
28 | backup_dir,
29 | display_path,
30 | hide_url,
31 | hide_value,
32 | is_installable_dir,
33 | rmtree,
34 | )
35 | from pip._internal.utils.subprocess import (
36 | CommandArgs,
37 | call_subprocess,
38 | format_command_args,
39 | make_command,
40 | )
41 |
42 | __all__ = ["vcs"]
43 |
44 |
45 | logger = logging.getLogger(__name__)
46 |
47 | AuthInfo = Tuple[Optional[str], Optional[str]]
48 |
49 |
50 | def is_url(name: str) -> bool:
51 | """
52 | Return true if the name looks like a URL.
53 | """
54 | scheme = urllib.parse.urlsplit(name).scheme
55 | if not scheme:
56 | return False
57 | return scheme in ["http", "https", "file", "ftp"] + vcs.all_schemes
58 |
59 |
60 | def make_vcs_requirement_url(
61 | repo_url: str, rev: str, project_name: str, subdir: Optional[str] = None
62 | ) -> str:
63 | """
64 | Return the URL for a VCS requirement.
65 |
66 | Args:
67 | repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+").
68 | project_name: the (unescaped) project name.
69 | """
70 | egg_project_name = project_name.replace("-", "_")
71 | req = f"{repo_url}@{rev}#egg={egg_project_name}"
72 | if subdir:
73 | req += f"&subdirectory={subdir}"
74 |
75 | return req
76 |
77 |
78 | def find_path_to_project_root_from_repo_root(
79 | location: str, repo_root: str
80 | ) -> Optional[str]:
81 | """
82 | Find the the Python project's root by searching up the filesystem from
83 | `location`. Return the path to project root relative to `repo_root`.
84 | Return None if the project root is `repo_root`, or cannot be found.
85 | """
86 | # find project root.
87 | orig_location = location
88 | while not is_installable_dir(location):
89 | last_location = location
90 | location = os.path.dirname(location)
91 | if location == last_location:
92 | # We've traversed up to the root of the filesystem without
93 | # finding a Python project.
94 | logger.warning(
95 | "Could not find a Python project for directory %s (tried all "
96 | "parent directories)",
97 | orig_location,
98 | )
99 | return None
100 |
101 | if os.path.samefile(repo_root, location):
102 | return None
103 |
104 | return os.path.relpath(location, repo_root)
105 |
106 |
107 | class RemoteNotFoundError(Exception):
108 | pass
109 |
110 |
111 | class RemoteNotValidError(Exception):
112 | def __init__(self, url: str):
113 | super().__init__(url)
114 | self.url = url
115 |
116 |
117 | @dataclass(frozen=True)
118 | class RevOptions:
119 | """
120 | Encapsulates a VCS-specific revision to install, along with any VCS
121 | install options.
122 |
123 | Args:
124 | vc_class: a VersionControl subclass.
125 | rev: the name of the revision to install.
126 | extra_args: a list of extra options.
127 | """
128 |
129 | vc_class: Type["VersionControl"]
130 | rev: Optional[str] = None
131 | extra_args: CommandArgs = field(default_factory=list)
132 | branch_name: Optional[str] = None
133 |
134 | def __repr__(self) -> str:
135 | return f"<RevOptions {self.vc_class.name}: rev={self.rev!r}>"
136 |
137 | @property
138 | def arg_rev(self) -> Optional[str]:
139 | if self.rev is None:
140 | return self.vc_class.default_arg_rev
141 |
142 | return self.rev
143 |
144 | def to_args(self) -> CommandArgs:
145 | """
146 | Return the VCS-specific command arguments.
147 | """
148 | args: CommandArgs = []
149 | rev = self.arg_rev
150 | if rev is not None:
151 | args += self.vc_class.get_base_rev_args(rev)
152 | args += self.extra_args
153 |
154 | return args
155 |
156 | def to_display(self) -> str:
157 | if not self.rev:
158 | return ""
159 |
160 | return f" (to revision {self.rev})"
161 |
162 | def make_new(self, rev: str) -> "RevOptions":
163 | """
164 | Make a copy of the current instance, but with a new rev.
165 |
166 | Args:
167 | rev: the name of the revision for the new object.
168 | """
169 | return self.vc_class.make_rev_options(rev, extra_args=self.extra_args)
170 |
171 |
172 | class VcsSupport:
173 | _registry: Dict[str, "VersionControl"] = {}
174 | schemes = ["ssh", "git", "hg", "bzr", "sftp", "svn"]
175 |
176 | def __init__(self) -> None:
177 | # Register more schemes with urlparse for various version control
178 | # systems
179 | urllib.parse.uses_netloc.extend(self.schemes)
180 | super().__init__()
181 |
182 | def __iter__(self) -> Iterator[str]:
183 | return self._registry.__iter__()
184 |
185 | @property
186 | def backends(self) -> List["VersionControl"]:
187 | return list(self._registry.values())
188 |
189 | @property
190 | def dirnames(self) -> List[str]:
191 | return [backend.dirname for backend in self.backends]
192 |
193 | @property
194 | def all_schemes(self) -> List[str]:
195 | schemes: List[str] = []
196 | for backend in self.backends:
197 | schemes.extend(backend.schemes)
198 | return schemes
199 |
200 | def register(self, cls: Type["VersionControl"]) -> None:
201 | if not hasattr(cls, "name"):
202 | logger.warning("Cannot register VCS %s", cls.__name__)
203 | return
204 | if cls.name not in self._registry:
205 | self._registry[cls.name] = cls()
206 | logger.debug("Registered VCS backend: %s", cls.name)
207 |
208 | def unregister(self, name: str) -> None:
209 | if name in self._registry:
210 | del self._registry[name]
211 |
212 | def get_backend_for_dir(self, location: str) -> Optional["VersionControl"]:
213 | """
214 | Return a VersionControl object if a repository of that type is found
215 | at the given directory.
216 | """
217 | vcs_backends = {}
218 | for vcs_backend in self._registry.values():
219 | repo_path = vcs_backend.get_repository_root(location)
220 | if not repo_path:
221 | continue
222 | logger.debug("Determine that %s uses VCS: %s", location, vcs_backend.name)
223 | vcs_backends[repo_path] = vcs_backend
224 |
225 | if not vcs_backends:
226 | return None
227 |
228 | # Choose the VCS in the inner-most directory. Since all repository
229 | # roots found here would be either `location` or one of its
230 | # parents, the longest path should have the most path components,
231 | # i.e. the backend representing the inner-most repository.
232 | inner_most_repo_path = max(vcs_backends, key=len)
233 | return vcs_backends[inner_most_repo_path]
234 |
235 | def get_backend_for_scheme(self, scheme: str) -> Optional["VersionControl"]:
236 | """
237 | Return a VersionControl object or None.
238 | """
239 | for vcs_backend in self._registry.values():
240 | if scheme in vcs_backend.schemes:
241 | return vcs_backend
242 | return None
243 |
244 | def get_backend(self, name: str) -> Optional["VersionControl"]:
245 | """
246 | Return a VersionControl object or None.
247 | """
248 | name = name.lower()
249 | return self._registry.get(name)
250 |
251 |
252 | vcs = VcsSupport()
253 |
254 |
255 | class VersionControl:
256 | name = ""
257 | dirname = ""
258 | repo_name = ""
259 | # List of supported schemes for this Version Control
260 | schemes: Tuple[str, ...] = ()
261 | # Iterable of environment variable names to pass to call_subprocess().
262 | unset_environ: Tuple[str, ...] = ()
263 | default_arg_rev: Optional[str] = None
264 |
265 | @classmethod
266 | def should_add_vcs_url_prefix(cls, remote_url: str) -> bool:
267 | """
268 | Return whether the vcs prefix (e.g. "git+") should be added to a
269 | repository's remote url when used in a requirement.
270 | """
271 | return not remote_url.lower().startswith(f"{cls.name}:")
272 |
273 | @classmethod
274 | def get_subdirectory(cls, location: str) -> Optional[str]:
275 | """
276 | Return the path to Python project root, relative to the repo root.
277 | Return None if the project root is in the repo root.
278 | """
279 | return None
280 |
281 | @classmethod
282 | def get_requirement_revision(cls, repo_dir: str) -> str:
283 | """
284 | Return the revision string that should be used in a requirement.
285 | """
286 | return cls.get_revision(repo_dir)
287 |
288 | @classmethod
289 | def get_src_requirement(cls, repo_dir: str, project_name: str) -> str:
290 | """
291 | Return the requirement string to use to redownload the files
292 | currently at the given repository directory.
293 |
294 | Args:
295 | project_name: the (unescaped) project name.
296 |
297 | The return value has a form similar to the following:
298 |
299 | {repository_url}@{revision}#egg={project_name}
300 | """
301 | repo_url = cls.get_remote_url(repo_dir)
302 |
303 | if cls.should_add_vcs_url_prefix(repo_url):
304 | repo_url = f"{cls.name}+{repo_url}"
305 |
306 | revision = cls.get_requirement_revision(repo_dir)
307 | subdir = cls.get_subdirectory(repo_dir)
308 | req = make_vcs_requirement_url(repo_url, revision, project_name, subdir=subdir)
309 |
310 | return req
311 |
312 | @staticmethod
313 | def get_base_rev_args(rev: str) -> List[str]:
314 | """
315 | Return the base revision arguments for a vcs command.
316 |
317 | Args:
318 | rev: the name of a revision to install. Cannot be None.
319 | """
320 | raise NotImplementedError
321 |
322 | def is_immutable_rev_checkout(self, url: str, dest: str) -> bool:
323 | """
324 | Return true if the commit hash checked out at dest matches
325 | the revision in url.
326 |
327 | Always return False, if the VCS does not support immutable commit
328 | hashes.
329 |
330 | This method does not check if there are local uncommitted changes
331 | in dest after checkout, as pip currently has no use case for that.
332 | """
333 | return False
334 |
335 | @classmethod
336 | def make_rev_options(
337 | cls, rev: Optional[str] = None, extra_args: Optional[CommandArgs] = None
338 | ) -> RevOptions:
339 | """
340 | Return a RevOptions object.
341 |
342 | Args:
343 | rev: the name of a revision to install.
344 | extra_args: a list of extra options.
345 | """
346 | return RevOptions(cls, rev, extra_args=extra_args or [])
347 |
348 | @classmethod
349 | def _is_local_repository(cls, repo: str) -> bool:
350 | """
351 | posix absolute paths start with os.path.sep,
352 | win32 ones start with drive (like c:\\folder)
353 | """
354 | drive, tail = os.path.splitdrive(repo)
355 | return repo.startswith(os.path.sep) or bool(drive)
356 |
357 | @classmethod
358 | def get_netloc_and_auth(
359 | cls, netloc: str, scheme: str
360 | ) -> Tuple[str, Tuple[Optional[str], Optional[str]]]:
361 | """
362 | Parse the repository URL's netloc, and return the new netloc to use
363 | along with auth information.
364 |
365 | Args:
366 | netloc: the original repository URL netloc.
367 | scheme: the repository URL's scheme without the vcs prefix.
368 |
369 | This is mainly for the Subversion class to override, so that auth
370 | information can be provided via the --username and --password options
371 | instead of through the URL. For other subclasses like Git without
372 | such an option, auth information must stay in the URL.
373 |
374 | Returns: (netloc, (username, password)).
375 | """
376 | return netloc, (None, None)
377 |
378 | @classmethod
379 | def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]:
380 | """
381 | Parse the repository URL to use, and return the URL, revision,
382 | and auth info to use.
383 |
384 | Returns: (url, rev, (username, password)).
385 | """
386 | scheme, netloc, path, query, frag = urllib.parse.urlsplit(url)
387 | if "+" not in scheme:
388 | raise ValueError(
389 | f"Sorry, {url!r} is a malformed VCS url. "
390 | "The format is <vcs>+<protocol>://<url>, "
391 | "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp"
392 | )
393 | # Remove the vcs prefix.
394 | scheme = scheme.split("+", 1)[1]
395 | netloc, user_pass = cls.get_netloc_and_auth(netloc, scheme)
396 | rev = None
397 | if "@" in path:
398 | path, rev = path.rsplit("@", 1)
399 | if not rev:
400 | raise InstallationError(
401 | f"The URL {url!r} has an empty revision (after @) "
402 | "which is not supported. Include a revision after @ "
403 | "or remove @ from the URL."
404 | )
405 | url = urllib.parse.urlunsplit((scheme, netloc, path, query, ""))
406 | return url, rev, user_pass
407 |
408 | @staticmethod
409 | def make_rev_args(
410 | username: Optional[str], password: Optional[HiddenText]
411 | ) -> CommandArgs:
412 | """
413 | Return the RevOptions "extra arguments" to use in obtain().
414 | """
415 | return []
416 |
417 | def get_url_rev_options(self, url: HiddenText) -> Tuple[HiddenText, RevOptions]:
418 | """
419 | Return the URL and RevOptions object to use in obtain(),
420 | as a tuple (url, rev_options).
421 | """
422 | secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret)
423 | username, secret_password = user_pass
424 | password: Optional[HiddenText] = None
425 | if secret_password is not None:
426 | password = hide_value(secret_password)
427 | extra_args = self.make_rev_args(username, password)
428 | rev_options = self.make_rev_options(rev, extra_args=extra_args)
429 |
430 | return hide_url(secret_url), rev_options
431 |
432 | @staticmethod
433 | def normalize_url(url: str) -> str:
434 | """
435 | Normalize a URL for comparison by unquoting it and removing any
436 | trailing slash.
437 | """
438 | return urllib.parse.unquote(url).rstrip("/")
439 |
440 | @classmethod
441 | def compare_urls(cls, url1: str, url2: str) -> bool:
442 | """
443 | Compare two repo URLs for identity, ignoring incidental differences.
444 | """
445 | return cls.normalize_url(url1) == cls.normalize_url(url2)
446 |
447 | def fetch_new(
448 | self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int
449 | ) -> None:
450 | """
451 | Fetch a revision from a repository, in the case that this is the
452 | first fetch from the repository.
453 |
454 | Args:
455 | dest: the directory to fetch the repository to.
456 | rev_options: a RevOptions object.
457 | verbosity: verbosity level.
458 | """
459 | raise NotImplementedError
460 |
461 | def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
462 | """
463 | Switch the repo at ``dest`` to point to ``URL``.
464 |
465 | Args:
466 | rev_options: a RevOptions object.
467 | """
468 | raise NotImplementedError
469 |
470 | def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
471 | """
472 | Update an already-existing repo to the given ``rev_options``.
473 |
474 | Args:
475 | rev_options: a RevOptions object.
476 | """
477 | raise NotImplementedError
478 |
479 | @classmethod
480 | def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:
481 | """
482 | Return whether the id of the current commit equals the given name.
483 |
484 | Args:
485 | dest: the repository directory.
486 | name: a string name.
487 | """
488 | raise NotImplementedError
489 |
490 | def obtain(self, dest: str, url: HiddenText, verbosity: int) -> None:
491 | """
492 | Install or update in editable mode the package represented by this
493 | VersionControl object.
494 |
495 | :param dest: the repository directory in which to install or update.
496 | :param url: the repository URL starting with a vcs prefix.
497 | :param verbosity: verbosity level.
498 | """
499 | url, rev_options = self.get_url_rev_options(url)
500 |
501 | if not os.path.exists(dest):
502 | self.fetch_new(dest, url, rev_options, verbosity=verbosity)
503 | return
504 |
505 | rev_display = rev_options.to_display()
506 | if self.is_repository_directory(dest):
507 | existing_url = self.get_remote_url(dest)
508 | if self.compare_urls(existing_url, url.secret):
509 | logger.debug(
510 | "%s in %s exists, and has correct URL (%s)",
511 | self.repo_name.title(),
512 | display_path(dest),
513 | url,
514 | )
515 | if not self.is_commit_id_equal(dest, rev_options.rev):
516 | logger.info(
517 | "Updating %s %s%s",
518 | display_path(dest),
519 | self.repo_name,
520 | rev_display,
521 | )
522 | self.update(dest, url, rev_options)
523 | else:
524 | logger.info("Skipping because already up-to-date.")
525 | return
526 |
527 | logger.warning(
528 | "%s %s in %s exists with URL %s",
529 | self.name,
530 | self.repo_name,
531 | display_path(dest),
532 | existing_url,
533 | )
534 | prompt = ("(s)witch, (i)gnore, (w)ipe, (b)ackup ", ("s", "i", "w", "b"))
535 | else:
536 | logger.warning(
537 | "Directory %s already exists, and is not a %s %s.",
538 | dest,
539 | self.name,
540 | self.repo_name,
541 | )
542 | # https://github.com/python/mypy/issues/1174
543 | prompt = ("(i)gnore, (w)ipe, (b)ackup ", ("i", "w", "b")) # type: ignore
544 |
545 | logger.warning(
546 | "The plan is to install the %s repository %s",
547 | self.name,
548 | url,
549 | )
550 | response = ask_path_exists(f"What to do? {prompt[0]}", prompt[1])
551 |
552 | if response == "a":
553 | sys.exit(-1)
554 |
555 | if response == "w":
556 | logger.warning("Deleting %s", display_path(dest))
557 | rmtree(dest)
558 | self.fetch_new(dest, url, rev_options, verbosity=verbosity)
559 | return
560 |
561 | if response == "b":
562 | dest_dir = backup_dir(dest)
563 | logger.warning("Backing up %s to %s", display_path(dest), dest_dir)
564 | shutil.move(dest, dest_dir)
565 | self.fetch_new(dest, url, rev_options, verbosity=verbosity)
566 | return
567 |
568 | # Do nothing if the response is "i".
569 | if response == "s":
570 | logger.info(
571 | "Switching %s %s to %s%s",
572 | self.repo_name,
573 | display_path(dest),
574 | url,
575 | rev_display,
576 | )
577 | self.switch(dest, url, rev_options)
578 |
579 | def unpack(self, location: str, url: HiddenText, verbosity: int) -> None:
580 | """
581 | Clean up current location and download the url repository
582 | (and vcs infos) into location
583 |
584 | :param url: the repository URL starting with a vcs prefix.
585 | :param verbosity: verbosity level.
586 | """
587 | if os.path.exists(location):
588 | rmtree(location)
589 | self.obtain(location, url=url, verbosity=verbosity)
590 |
591 | @classmethod
592 | def get_remote_url(cls, location: str) -> str:
593 | """
594 | Return the url used at location
595 |
596 | Raises RemoteNotFoundError if the repository does not have a remote
597 | url configured.
598 | """
599 | raise NotImplementedError
600 |
601 | @classmethod
602 | def get_revision(cls, location: str) -> str:
603 | """
604 | Return the current commit id of the files at the given location.
605 | """
606 | raise NotImplementedError
607 |
608 | @classmethod
609 | def run_command(
610 | cls,
611 | cmd: Union[List[str], CommandArgs],
612 | show_stdout: bool = True,
613 | cwd: Optional[str] = None,
614 | on_returncode: 'Literal["raise", "warn", "ignore"]' = "raise",
615 | extra_ok_returncodes: Optional[Iterable[int]] = None,
616 | command_desc: Optional[str] = None,
617 | extra_environ: Optional[Mapping[str, Any]] = None,
618 | spinner: Optional[SpinnerInterface] = None,
619 | log_failed_cmd: bool = True,
620 | stdout_only: bool = False,
621 | ) -> str:
622 | """
623 | Run a VCS subcommand
624 | This is simply a wrapper around call_subprocess that adds the VCS
625 | command name, and checks that the VCS is available
626 | """
627 | cmd = make_command(cls.name, *cmd)
628 | if command_desc is None:
629 | command_desc = format_command_args(cmd)
630 | try:
631 | return call_subprocess(
632 | cmd,
633 | show_stdout,
634 | cwd,
635 | on_returncode=on_returncode,
636 | extra_ok_returncodes=extra_ok_returncodes,
637 | command_desc=command_desc,
638 | extra_environ=extra_environ,
639 | unset_environ=cls.unset_environ,
640 | spinner=spinner,
641 | log_failed_cmd=log_failed_cmd,
642 | stdout_only=stdout_only,
643 | )
644 | except NotADirectoryError:
645 | raise BadCommand(f"Cannot find command {cls.name!r} - invalid PATH")
646 | except FileNotFoundError:
647 | # errno.ENOENT = no such file or directory
648 | # In other words, the VCS executable isn't available
649 | raise BadCommand(
650 | f"Cannot find command {cls.name!r} - do you have "
651 | f"{cls.name!r} installed and in your PATH?"
652 | )
653 | except PermissionError:
654 | # errno.EACCES = Permission denied
655 | # This error occurs, for instance, when the command is installed
656 | # only for another user. So, the current user don't have
657 | # permission to call the other user command.
658 | raise BadCommand(
659 | f"No permission to execute {cls.name!r} - install it "
660 | f"locally, globally (ask admin), or check your PATH. "
661 | f"See possible solutions at "
662 | f"https://pip.pypa.io/en/latest/reference/pip_freeze/"
663 | f"#fixing-permission-denied."
664 | )
665 |
666 | @classmethod
667 | def is_repository_directory(cls, path: str) -> bool:
668 | """
669 | Return whether a directory path is a repository directory.
670 | """
671 | logger.debug("Checking in %s for %s (%s)...", path, cls.dirname, cls.name)
672 | return os.path.exists(os.path.join(path, cls.dirname))
673 |
674 | @classmethod
675 | def get_repository_root(cls, location: str) -> Optional[str]:
676 | """
677 | Return the "root" (top-level) directory controlled by the vcs,
678 | or `None` if the directory is not in any.
679 |
680 | It is meant to be overridden to implement smarter detection
681 | mechanisms for specific vcs.
682 |
683 | This can do more than is_repository_directory() alone. For
684 | example, the Git override checks that Git is actually available.
685 | """
686 | if cls.is_repository_directory(location):
687 | return location
688 | return None
689 |
```