This is page 39 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/rich/align.py:
--------------------------------------------------------------------------------
```python
1 | import sys
2 | from itertools import chain
3 | from typing import TYPE_CHECKING, Iterable, Optional
4 |
5 | if sys.version_info >= (3, 8):
6 | from typing import Literal
7 | else:
8 | from pip._vendor.typing_extensions import Literal # pragma: no cover
9 |
10 | from .constrain import Constrain
11 | from .jupyter import JupyterMixin
12 | from .measure import Measurement
13 | from .segment import Segment
14 | from .style import StyleType
15 |
16 | if TYPE_CHECKING:
17 | from .console import Console, ConsoleOptions, RenderableType, RenderResult
18 |
19 | AlignMethod = Literal["left", "center", "right"]
20 | VerticalAlignMethod = Literal["top", "middle", "bottom"]
21 |
22 |
23 | class Align(JupyterMixin):
24 | """Align a renderable by adding spaces if necessary.
25 |
26 | Args:
27 | renderable (RenderableType): A console renderable.
28 | align (AlignMethod): One of "left", "center", or "right""
29 | style (StyleType, optional): An optional style to apply to the background.
30 | vertical (Optional[VerticalAlignMethod], optional): Optional vertical align, one of "top", "middle", or "bottom". Defaults to None.
31 | pad (bool, optional): Pad the right with spaces. Defaults to True.
32 | width (int, optional): Restrict contents to given width, or None to use default width. Defaults to None.
33 | height (int, optional): Set height of align renderable, or None to fit to contents. Defaults to None.
34 |
35 | Raises:
36 | ValueError: if ``align`` is not one of the expected values.
37 | """
38 |
39 | def __init__(
40 | self,
41 | renderable: "RenderableType",
42 | align: AlignMethod = "left",
43 | style: Optional[StyleType] = None,
44 | *,
45 | vertical: Optional[VerticalAlignMethod] = None,
46 | pad: bool = True,
47 | width: Optional[int] = None,
48 | height: Optional[int] = None,
49 | ) -> None:
50 | if align not in ("left", "center", "right"):
51 | raise ValueError(
52 | f'invalid value for align, expected "left", "center", or "right" (not {align!r})'
53 | )
54 | if vertical is not None and vertical not in ("top", "middle", "bottom"):
55 | raise ValueError(
56 | f'invalid value for vertical, expected "top", "middle", or "bottom" (not {vertical!r})'
57 | )
58 | self.renderable = renderable
59 | self.align = align
60 | self.style = style
61 | self.vertical = vertical
62 | self.pad = pad
63 | self.width = width
64 | self.height = height
65 |
66 | def __repr__(self) -> str:
67 | return f"Align({self.renderable!r}, {self.align!r})"
68 |
69 | @classmethod
70 | def left(
71 | cls,
72 | renderable: "RenderableType",
73 | style: Optional[StyleType] = None,
74 | *,
75 | vertical: Optional[VerticalAlignMethod] = None,
76 | pad: bool = True,
77 | width: Optional[int] = None,
78 | height: Optional[int] = None,
79 | ) -> "Align":
80 | """Align a renderable to the left."""
81 | return cls(
82 | renderable,
83 | "left",
84 | style=style,
85 | vertical=vertical,
86 | pad=pad,
87 | width=width,
88 | height=height,
89 | )
90 |
91 | @classmethod
92 | def center(
93 | cls,
94 | renderable: "RenderableType",
95 | style: Optional[StyleType] = None,
96 | *,
97 | vertical: Optional[VerticalAlignMethod] = None,
98 | pad: bool = True,
99 | width: Optional[int] = None,
100 | height: Optional[int] = None,
101 | ) -> "Align":
102 | """Align a renderable to the center."""
103 | return cls(
104 | renderable,
105 | "center",
106 | style=style,
107 | vertical=vertical,
108 | pad=pad,
109 | width=width,
110 | height=height,
111 | )
112 |
113 | @classmethod
114 | def right(
115 | cls,
116 | renderable: "RenderableType",
117 | style: Optional[StyleType] = None,
118 | *,
119 | vertical: Optional[VerticalAlignMethod] = None,
120 | pad: bool = True,
121 | width: Optional[int] = None,
122 | height: Optional[int] = None,
123 | ) -> "Align":
124 | """Align a renderable to the right."""
125 | return cls(
126 | renderable,
127 | "right",
128 | style=style,
129 | vertical=vertical,
130 | pad=pad,
131 | width=width,
132 | height=height,
133 | )
134 |
135 | def __rich_console__(
136 | self, console: "Console", options: "ConsoleOptions"
137 | ) -> "RenderResult":
138 | align = self.align
139 | width = console.measure(self.renderable, options=options).maximum
140 | rendered = console.render(
141 | Constrain(
142 | self.renderable, width if self.width is None else min(width, self.width)
143 | ),
144 | options.update(height=None),
145 | )
146 | lines = list(Segment.split_lines(rendered))
147 | width, height = Segment.get_shape(lines)
148 | lines = Segment.set_shape(lines, width, height)
149 | new_line = Segment.line()
150 | excess_space = options.max_width - width
151 | style = console.get_style(self.style) if self.style is not None else None
152 |
153 | def generate_segments() -> Iterable[Segment]:
154 | if excess_space <= 0:
155 | # Exact fit
156 | for line in lines:
157 | yield from line
158 | yield new_line
159 |
160 | elif align == "left":
161 | # Pad on the right
162 | pad = Segment(" " * excess_space, style) if self.pad else None
163 | for line in lines:
164 | yield from line
165 | if pad:
166 | yield pad
167 | yield new_line
168 |
169 | elif align == "center":
170 | # Pad left and right
171 | left = excess_space // 2
172 | pad = Segment(" " * left, style)
173 | pad_right = (
174 | Segment(" " * (excess_space - left), style) if self.pad else None
175 | )
176 | for line in lines:
177 | if left:
178 | yield pad
179 | yield from line
180 | if pad_right:
181 | yield pad_right
182 | yield new_line
183 |
184 | elif align == "right":
185 | # Padding on left
186 | pad = Segment(" " * excess_space, style)
187 | for line in lines:
188 | yield pad
189 | yield from line
190 | yield new_line
191 |
192 | blank_line = (
193 | Segment(f"{' ' * (self.width or options.max_width)}\n", style)
194 | if self.pad
195 | else Segment("\n")
196 | )
197 |
198 | def blank_lines(count: int) -> Iterable[Segment]:
199 | if count > 0:
200 | for _ in range(count):
201 | yield blank_line
202 |
203 | vertical_height = self.height or options.height
204 | iter_segments: Iterable[Segment]
205 | if self.vertical and vertical_height is not None:
206 | if self.vertical == "top":
207 | bottom_space = vertical_height - height
208 | iter_segments = chain(generate_segments(), blank_lines(bottom_space))
209 | elif self.vertical == "middle":
210 | top_space = (vertical_height - height) // 2
211 | bottom_space = vertical_height - top_space - height
212 | iter_segments = chain(
213 | blank_lines(top_space),
214 | generate_segments(),
215 | blank_lines(bottom_space),
216 | )
217 | else: # self.vertical == "bottom":
218 | top_space = vertical_height - height
219 | iter_segments = chain(blank_lines(top_space), generate_segments())
220 | else:
221 | iter_segments = generate_segments()
222 | if self.style:
223 | style = console.get_style(self.style)
224 | iter_segments = Segment.apply_style(iter_segments, style)
225 | yield from iter_segments
226 |
227 | def __rich_measure__(
228 | self, console: "Console", options: "ConsoleOptions"
229 | ) -> Measurement:
230 | measurement = Measurement.get(console, options, self.renderable)
231 | return measurement
232 |
233 |
234 | class VerticalCenter(JupyterMixin):
235 | """Vertically aligns a renderable.
236 |
237 | Warn:
238 | This class is deprecated and may be removed in a future version. Use Align class with
239 | `vertical="middle"`.
240 |
241 | Args:
242 | renderable (RenderableType): A renderable object.
243 | """
244 |
245 | def __init__(
246 | self,
247 | renderable: "RenderableType",
248 | style: Optional[StyleType] = None,
249 | ) -> None:
250 | self.renderable = renderable
251 | self.style = style
252 |
253 | def __repr__(self) -> str:
254 | return f"VerticalCenter({self.renderable!r})"
255 |
256 | def __rich_console__(
257 | self, console: "Console", options: "ConsoleOptions"
258 | ) -> "RenderResult":
259 | style = console.get_style(self.style) if self.style is not None else None
260 | lines = console.render_lines(
261 | self.renderable, options.update(height=None), pad=False
262 | )
263 | width, _height = Segment.get_shape(lines)
264 | new_line = Segment.line()
265 | height = options.height or options.size.height
266 | top_space = (height - len(lines)) // 2
267 | bottom_space = height - top_space - len(lines)
268 | blank_line = Segment(f"{' ' * width}", style)
269 |
270 | def blank_lines(count: int) -> Iterable[Segment]:
271 | for _ in range(count):
272 | yield blank_line
273 | yield new_line
274 |
275 | if top_space > 0:
276 | yield from blank_lines(top_space)
277 | for line in lines:
278 | yield from line
279 | yield new_line
280 | if bottom_space > 0:
281 | yield from blank_lines(bottom_space)
282 |
283 | def __rich_measure__(
284 | self, console: "Console", options: "ConsoleOptions"
285 | ) -> Measurement:
286 | measurement = Measurement.get(console, options, self.renderable)
287 | return measurement
288 |
289 |
290 | if __name__ == "__main__": # pragma: no cover
291 | from pip._vendor.rich.console import Console, Group
292 | from pip._vendor.rich.highlighter import ReprHighlighter
293 | from pip._vendor.rich.panel import Panel
294 |
295 | highlighter = ReprHighlighter()
296 | console = Console()
297 |
298 | panel = Panel(
299 | Group(
300 | Align.left(highlighter("align='left'")),
301 | Align.center(highlighter("align='center'")),
302 | Align.right(highlighter("align='right'")),
303 | ),
304 | width=60,
305 | style="on dark_blue",
306 | title="Align",
307 | )
308 |
309 | console.print(
310 | Align.center(panel, vertical="middle", style="on red", height=console.height)
311 | )
312 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/cache.py:
--------------------------------------------------------------------------------
```python
1 | """Cache Management
2 | """
3 |
4 | import hashlib
5 | import json
6 | import logging
7 | import os
8 | from pathlib import Path
9 | from typing import Any, Dict, List, Optional
10 |
11 | from pip._vendor.packaging.tags import Tag, interpreter_name, interpreter_version
12 | from pip._vendor.packaging.utils import canonicalize_name
13 |
14 | from pip._internal.exceptions import InvalidWheelFilename
15 | from pip._internal.models.direct_url import DirectUrl
16 | from pip._internal.models.link import Link
17 | from pip._internal.models.wheel import Wheel
18 | from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
19 | from pip._internal.utils.urls import path_to_url
20 |
21 | logger = logging.getLogger(__name__)
22 |
23 | ORIGIN_JSON_NAME = "origin.json"
24 |
25 |
26 | def _hash_dict(d: Dict[str, str]) -> str:
27 | """Return a stable sha224 of a dictionary."""
28 | s = json.dumps(d, sort_keys=True, separators=(",", ":"), ensure_ascii=True)
29 | return hashlib.sha224(s.encode("ascii")).hexdigest()
30 |
31 |
32 | class Cache:
33 | """An abstract class - provides cache directories for data from links
34 |
35 | :param cache_dir: The root of the cache.
36 | """
37 |
38 | def __init__(self, cache_dir: str) -> None:
39 | super().__init__()
40 | assert not cache_dir or os.path.isabs(cache_dir)
41 | self.cache_dir = cache_dir or None
42 |
43 | def _get_cache_path_parts(self, link: Link) -> List[str]:
44 | """Get parts of part that must be os.path.joined with cache_dir"""
45 |
46 | # We want to generate an url to use as our cache key, we don't want to
47 | # just reuse the URL because it might have other items in the fragment
48 | # and we don't care about those.
49 | key_parts = {"url": link.url_without_fragment}
50 | if link.hash_name is not None and link.hash is not None:
51 | key_parts[link.hash_name] = link.hash
52 | if link.subdirectory_fragment:
53 | key_parts["subdirectory"] = link.subdirectory_fragment
54 |
55 | # Include interpreter name, major and minor version in cache key
56 | # to cope with ill-behaved sdists that build a different wheel
57 | # depending on the python version their setup.py is being run on,
58 | # and don't encode the difference in compatibility tags.
59 | # https://github.com/pypa/pip/issues/7296
60 | key_parts["interpreter_name"] = interpreter_name()
61 | key_parts["interpreter_version"] = interpreter_version()
62 |
63 | # Encode our key url with sha224, we'll use this because it has similar
64 | # security properties to sha256, but with a shorter total output (and
65 | # thus less secure). However the differences don't make a lot of
66 | # difference for our use case here.
67 | hashed = _hash_dict(key_parts)
68 |
69 | # We want to nest the directories some to prevent having a ton of top
70 | # level directories where we might run out of sub directories on some
71 | # FS.
72 | parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]]
73 |
74 | return parts
75 |
76 | def _get_candidates(self, link: Link, canonical_package_name: str) -> List[Any]:
77 | can_not_cache = not self.cache_dir or not canonical_package_name or not link
78 | if can_not_cache:
79 | return []
80 |
81 | path = self.get_path_for_link(link)
82 | if os.path.isdir(path):
83 | return [(candidate, path) for candidate in os.listdir(path)]
84 | return []
85 |
86 | def get_path_for_link(self, link: Link) -> str:
87 | """Return a directory to store cached items in for link."""
88 | raise NotImplementedError()
89 |
90 | def get(
91 | self,
92 | link: Link,
93 | package_name: Optional[str],
94 | supported_tags: List[Tag],
95 | ) -> Link:
96 | """Returns a link to a cached item if it exists, otherwise returns the
97 | passed link.
98 | """
99 | raise NotImplementedError()
100 |
101 |
102 | class SimpleWheelCache(Cache):
103 | """A cache of wheels for future installs."""
104 |
105 | def __init__(self, cache_dir: str) -> None:
106 | super().__init__(cache_dir)
107 |
108 | def get_path_for_link(self, link: Link) -> str:
109 | """Return a directory to store cached wheels for link
110 |
111 | Because there are M wheels for any one sdist, we provide a directory
112 | to cache them in, and then consult that directory when looking up
113 | cache hits.
114 |
115 | We only insert things into the cache if they have plausible version
116 | numbers, so that we don't contaminate the cache with things that were
117 | not unique. E.g. ./package might have dozens of installs done for it
118 | and build a version of 0.0...and if we built and cached a wheel, we'd
119 | end up using the same wheel even if the source has been edited.
120 |
121 | :param link: The link of the sdist for which this will cache wheels.
122 | """
123 | parts = self._get_cache_path_parts(link)
124 | assert self.cache_dir
125 | # Store wheels within the root cache_dir
126 | return os.path.join(self.cache_dir, "wheels", *parts)
127 |
128 | def get(
129 | self,
130 | link: Link,
131 | package_name: Optional[str],
132 | supported_tags: List[Tag],
133 | ) -> Link:
134 | candidates = []
135 |
136 | if not package_name:
137 | return link
138 |
139 | canonical_package_name = canonicalize_name(package_name)
140 | for wheel_name, wheel_dir in self._get_candidates(link, canonical_package_name):
141 | try:
142 | wheel = Wheel(wheel_name)
143 | except InvalidWheelFilename:
144 | continue
145 | if canonicalize_name(wheel.name) != canonical_package_name:
146 | logger.debug(
147 | "Ignoring cached wheel %s for %s as it "
148 | "does not match the expected distribution name %s.",
149 | wheel_name,
150 | link,
151 | package_name,
152 | )
153 | continue
154 | if not wheel.supported(supported_tags):
155 | # Built for a different python/arch/etc
156 | continue
157 | candidates.append(
158 | (
159 | wheel.support_index_min(supported_tags),
160 | wheel_name,
161 | wheel_dir,
162 | )
163 | )
164 |
165 | if not candidates:
166 | return link
167 |
168 | _, wheel_name, wheel_dir = min(candidates)
169 | return Link(path_to_url(os.path.join(wheel_dir, wheel_name)))
170 |
171 |
172 | class EphemWheelCache(SimpleWheelCache):
173 | """A SimpleWheelCache that creates it's own temporary cache directory"""
174 |
175 | def __init__(self) -> None:
176 | self._temp_dir = TempDirectory(
177 | kind=tempdir_kinds.EPHEM_WHEEL_CACHE,
178 | globally_managed=True,
179 | )
180 |
181 | super().__init__(self._temp_dir.path)
182 |
183 |
184 | class CacheEntry:
185 | def __init__(
186 | self,
187 | link: Link,
188 | persistent: bool,
189 | ):
190 | self.link = link
191 | self.persistent = persistent
192 | self.origin: Optional[DirectUrl] = None
193 | origin_direct_url_path = Path(self.link.file_path).parent / ORIGIN_JSON_NAME
194 | if origin_direct_url_path.exists():
195 | try:
196 | self.origin = DirectUrl.from_json(
197 | origin_direct_url_path.read_text(encoding="utf-8")
198 | )
199 | except Exception as e:
200 | logger.warning(
201 | "Ignoring invalid cache entry origin file %s for %s (%s)",
202 | origin_direct_url_path,
203 | link.filename,
204 | e,
205 | )
206 |
207 |
208 | class WheelCache(Cache):
209 | """Wraps EphemWheelCache and SimpleWheelCache into a single Cache
210 |
211 | This Cache allows for gracefully degradation, using the ephem wheel cache
212 | when a certain link is not found in the simple wheel cache first.
213 | """
214 |
215 | def __init__(self, cache_dir: str) -> None:
216 | super().__init__(cache_dir)
217 | self._wheel_cache = SimpleWheelCache(cache_dir)
218 | self._ephem_cache = EphemWheelCache()
219 |
220 | def get_path_for_link(self, link: Link) -> str:
221 | return self._wheel_cache.get_path_for_link(link)
222 |
223 | def get_ephem_path_for_link(self, link: Link) -> str:
224 | return self._ephem_cache.get_path_for_link(link)
225 |
226 | def get(
227 | self,
228 | link: Link,
229 | package_name: Optional[str],
230 | supported_tags: List[Tag],
231 | ) -> Link:
232 | cache_entry = self.get_cache_entry(link, package_name, supported_tags)
233 | if cache_entry is None:
234 | return link
235 | return cache_entry.link
236 |
237 | def get_cache_entry(
238 | self,
239 | link: Link,
240 | package_name: Optional[str],
241 | supported_tags: List[Tag],
242 | ) -> Optional[CacheEntry]:
243 | """Returns a CacheEntry with a link to a cached item if it exists or
244 | None. The cache entry indicates if the item was found in the persistent
245 | or ephemeral cache.
246 | """
247 | retval = self._wheel_cache.get(
248 | link=link,
249 | package_name=package_name,
250 | supported_tags=supported_tags,
251 | )
252 | if retval is not link:
253 | return CacheEntry(retval, persistent=True)
254 |
255 | retval = self._ephem_cache.get(
256 | link=link,
257 | package_name=package_name,
258 | supported_tags=supported_tags,
259 | )
260 | if retval is not link:
261 | return CacheEntry(retval, persistent=False)
262 |
263 | return None
264 |
265 | @staticmethod
266 | def record_download_origin(cache_dir: str, download_info: DirectUrl) -> None:
267 | origin_path = Path(cache_dir) / ORIGIN_JSON_NAME
268 | if origin_path.exists():
269 | try:
270 | origin = DirectUrl.from_json(origin_path.read_text(encoding="utf-8"))
271 | except Exception as e:
272 | logger.warning(
273 | "Could not read origin file %s in cache entry (%s). "
274 | "Will attempt to overwrite it.",
275 | origin_path,
276 | e,
277 | )
278 | else:
279 | # TODO: use DirectUrl.equivalent when
280 | # https://github.com/pypa/pip/pull/10564 is merged.
281 | if origin.url != download_info.url:
282 | logger.warning(
283 | "Origin URL %s in cache entry %s does not match download URL "
284 | "%s. This is likely a pip bug or a cache corruption issue. "
285 | "Will overwrite it with the new value.",
286 | origin.url,
287 | cache_dir,
288 | download_info.url,
289 | )
290 | origin_path.write_text(download_info.to_json(), encoding="utf-8")
291 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/charset_normalizer/cli/__main__.py:
--------------------------------------------------------------------------------
```python
1 | import argparse
2 | import sys
3 | from json import dumps
4 | from os.path import abspath, basename, dirname, join, realpath
5 | from platform import python_version
6 | from typing import List, Optional
7 | from unicodedata import unidata_version
8 |
9 | import charset_normalizer.md as md_module
10 | from charset_normalizer import from_fp
11 | from charset_normalizer.models import CliDetectionResult
12 | from charset_normalizer.version import __version__
13 |
14 |
15 | def query_yes_no(question: str, default: str = "yes") -> bool:
16 | """Ask a yes/no question via input() and return their answer.
17 |
18 | "question" is a string that is presented to the user.
19 | "default" is the presumed answer if the user just hits <Enter>.
20 | It must be "yes" (the default), "no" or None (meaning
21 | an answer is required of the user).
22 |
23 | The "answer" return value is True for "yes" or False for "no".
24 |
25 | Credit goes to (c) https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input
26 | """
27 | valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False}
28 | if default is None:
29 | prompt = " [y/n] "
30 | elif default == "yes":
31 | prompt = " [Y/n] "
32 | elif default == "no":
33 | prompt = " [y/N] "
34 | else:
35 | raise ValueError("invalid default answer: '%s'" % default)
36 |
37 | while True:
38 | sys.stdout.write(question + prompt)
39 | choice = input().lower()
40 | if default is not None and choice == "":
41 | return valid[default]
42 | elif choice in valid:
43 | return valid[choice]
44 | else:
45 | sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n")
46 |
47 |
48 | def cli_detect(argv: Optional[List[str]] = None) -> int:
49 | """
50 | CLI assistant using ARGV and ArgumentParser
51 | :param argv:
52 | :return: 0 if everything is fine, anything else equal trouble
53 | """
54 | parser = argparse.ArgumentParser(
55 | description="The Real First Universal Charset Detector. "
56 | "Discover originating encoding used on text file. "
57 | "Normalize text to unicode."
58 | )
59 |
60 | parser.add_argument(
61 | "files", type=argparse.FileType("rb"), nargs="+", help="File(s) to be analysed"
62 | )
63 | parser.add_argument(
64 | "-v",
65 | "--verbose",
66 | action="store_true",
67 | default=False,
68 | dest="verbose",
69 | help="Display complementary information about file if any. "
70 | "Stdout will contain logs about the detection process.",
71 | )
72 | parser.add_argument(
73 | "-a",
74 | "--with-alternative",
75 | action="store_true",
76 | default=False,
77 | dest="alternatives",
78 | help="Output complementary possibilities if any. Top-level JSON WILL be a list.",
79 | )
80 | parser.add_argument(
81 | "-n",
82 | "--normalize",
83 | action="store_true",
84 | default=False,
85 | dest="normalize",
86 | help="Permit to normalize input file. If not set, program does not write anything.",
87 | )
88 | parser.add_argument(
89 | "-m",
90 | "--minimal",
91 | action="store_true",
92 | default=False,
93 | dest="minimal",
94 | help="Only output the charset detected to STDOUT. Disabling JSON output.",
95 | )
96 | parser.add_argument(
97 | "-r",
98 | "--replace",
99 | action="store_true",
100 | default=False,
101 | dest="replace",
102 | help="Replace file when trying to normalize it instead of creating a new one.",
103 | )
104 | parser.add_argument(
105 | "-f",
106 | "--force",
107 | action="store_true",
108 | default=False,
109 | dest="force",
110 | help="Replace file without asking if you are sure, use this flag with caution.",
111 | )
112 | parser.add_argument(
113 | "-i",
114 | "--no-preemptive",
115 | action="store_true",
116 | default=False,
117 | dest="no_preemptive",
118 | help="Disable looking at a charset declaration to hint the detector.",
119 | )
120 | parser.add_argument(
121 | "-t",
122 | "--threshold",
123 | action="store",
124 | default=0.2,
125 | type=float,
126 | dest="threshold",
127 | help="Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1.",
128 | )
129 | parser.add_argument(
130 | "--version",
131 | action="version",
132 | version="Charset-Normalizer {} - Python {} - Unicode {} - SpeedUp {}".format(
133 | __version__,
134 | python_version(),
135 | unidata_version,
136 | "OFF" if md_module.__file__.lower().endswith(".py") else "ON",
137 | ),
138 | help="Show version information and exit.",
139 | )
140 |
141 | args = parser.parse_args(argv)
142 |
143 | if args.replace is True and args.normalize is False:
144 | if args.files:
145 | for my_file in args.files:
146 | my_file.close()
147 | print("Use --replace in addition of --normalize only.", file=sys.stderr)
148 | return 1
149 |
150 | if args.force is True and args.replace is False:
151 | if args.files:
152 | for my_file in args.files:
153 | my_file.close()
154 | print("Use --force in addition of --replace only.", file=sys.stderr)
155 | return 1
156 |
157 | if args.threshold < 0.0 or args.threshold > 1.0:
158 | if args.files:
159 | for my_file in args.files:
160 | my_file.close()
161 | print("--threshold VALUE should be between 0. AND 1.", file=sys.stderr)
162 | return 1
163 |
164 | x_ = []
165 |
166 | for my_file in args.files:
167 | matches = from_fp(
168 | my_file,
169 | threshold=args.threshold,
170 | explain=args.verbose,
171 | preemptive_behaviour=args.no_preemptive is False,
172 | )
173 |
174 | best_guess = matches.best()
175 |
176 | if best_guess is None:
177 | print(
178 | 'Unable to identify originating encoding for "{}". {}'.format(
179 | my_file.name,
180 | (
181 | "Maybe try increasing maximum amount of chaos."
182 | if args.threshold < 1.0
183 | else ""
184 | ),
185 | ),
186 | file=sys.stderr,
187 | )
188 | x_.append(
189 | CliDetectionResult(
190 | abspath(my_file.name),
191 | None,
192 | [],
193 | [],
194 | "Unknown",
195 | [],
196 | False,
197 | 1.0,
198 | 0.0,
199 | None,
200 | True,
201 | )
202 | )
203 | else:
204 | x_.append(
205 | CliDetectionResult(
206 | abspath(my_file.name),
207 | best_guess.encoding,
208 | best_guess.encoding_aliases,
209 | [
210 | cp
211 | for cp in best_guess.could_be_from_charset
212 | if cp != best_guess.encoding
213 | ],
214 | best_guess.language,
215 | best_guess.alphabets,
216 | best_guess.bom,
217 | best_guess.percent_chaos,
218 | best_guess.percent_coherence,
219 | None,
220 | True,
221 | )
222 | )
223 |
224 | if len(matches) > 1 and args.alternatives:
225 | for el in matches:
226 | if el != best_guess:
227 | x_.append(
228 | CliDetectionResult(
229 | abspath(my_file.name),
230 | el.encoding,
231 | el.encoding_aliases,
232 | [
233 | cp
234 | for cp in el.could_be_from_charset
235 | if cp != el.encoding
236 | ],
237 | el.language,
238 | el.alphabets,
239 | el.bom,
240 | el.percent_chaos,
241 | el.percent_coherence,
242 | None,
243 | False,
244 | )
245 | )
246 |
247 | if args.normalize is True:
248 | if best_guess.encoding.startswith("utf") is True:
249 | print(
250 | '"{}" file does not need to be normalized, as it already came from unicode.'.format(
251 | my_file.name
252 | ),
253 | file=sys.stderr,
254 | )
255 | if my_file.closed is False:
256 | my_file.close()
257 | continue
258 |
259 | dir_path = dirname(realpath(my_file.name))
260 | file_name = basename(realpath(my_file.name))
261 |
262 | o_: List[str] = file_name.split(".")
263 |
264 | if args.replace is False:
265 | o_.insert(-1, best_guess.encoding)
266 | if my_file.closed is False:
267 | my_file.close()
268 | elif (
269 | args.force is False
270 | and query_yes_no(
271 | 'Are you sure to normalize "{}" by replacing it ?'.format(
272 | my_file.name
273 | ),
274 | "no",
275 | )
276 | is False
277 | ):
278 | if my_file.closed is False:
279 | my_file.close()
280 | continue
281 |
282 | try:
283 | x_[0].unicode_path = join(dir_path, ".".join(o_))
284 |
285 | with open(x_[0].unicode_path, "wb") as fp:
286 | fp.write(best_guess.output())
287 | except IOError as e:
288 | print(str(e), file=sys.stderr)
289 | if my_file.closed is False:
290 | my_file.close()
291 | return 2
292 |
293 | if my_file.closed is False:
294 | my_file.close()
295 |
296 | if args.minimal is False:
297 | print(
298 | dumps(
299 | [el.__dict__ for el in x_] if len(x_) > 1 else x_[0].__dict__,
300 | ensure_ascii=True,
301 | indent=4,
302 | )
303 | )
304 | else:
305 | for my_file in args.files:
306 | print(
307 | ", ".join(
308 | [
309 | el.encoding or "undefined"
310 | for el in x_
311 | if el.path == abspath(my_file.name)
312 | ]
313 | )
314 | )
315 |
316 | return 0
317 |
318 |
319 | if __name__ == "__main__":
320 | cli_detect()
321 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/build_env.py:
--------------------------------------------------------------------------------
```python
1 | """Build Environment used for isolation during sdist building
2 | """
3 |
4 | import logging
5 | import os
6 | import pathlib
7 | import site
8 | import sys
9 | import textwrap
10 | from collections import OrderedDict
11 | from types import TracebackType
12 | from typing import TYPE_CHECKING, Iterable, List, Optional, Set, Tuple, Type, Union
13 |
14 | from pip._vendor.certifi import where
15 | from pip._vendor.packaging.version import Version
16 |
17 | from pip import __file__ as pip_location
18 | from pip._internal.cli.spinners import open_spinner
19 | from pip._internal.locations import get_platlib, get_purelib, get_scheme
20 | from pip._internal.metadata import get_default_environment, get_environment
21 | from pip._internal.utils.logging import VERBOSE
22 | from pip._internal.utils.packaging import get_requirement
23 | from pip._internal.utils.subprocess import call_subprocess
24 | from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
25 |
26 | if TYPE_CHECKING:
27 | from pip._internal.index.package_finder import PackageFinder
28 |
29 | logger = logging.getLogger(__name__)
30 |
31 |
32 | def _dedup(a: str, b: str) -> Union[Tuple[str], Tuple[str, str]]:
33 | return (a, b) if a != b else (a,)
34 |
35 |
36 | class _Prefix:
37 | def __init__(self, path: str) -> None:
38 | self.path = path
39 | self.setup = False
40 | scheme = get_scheme("", prefix=path)
41 | self.bin_dir = scheme.scripts
42 | self.lib_dirs = _dedup(scheme.purelib, scheme.platlib)
43 |
44 |
45 | def get_runnable_pip() -> str:
46 | """Get a file to pass to a Python executable, to run the currently-running pip.
47 |
48 | This is used to run a pip subprocess, for installing requirements into the build
49 | environment.
50 | """
51 | source = pathlib.Path(pip_location).resolve().parent
52 |
53 | if not source.is_dir():
54 | # This would happen if someone is using pip from inside a zip file. In that
55 | # case, we can use that directly.
56 | return str(source)
57 |
58 | return os.fsdecode(source / "__pip-runner__.py")
59 |
60 |
61 | def _get_system_sitepackages() -> Set[str]:
62 | """Get system site packages
63 |
64 | Usually from site.getsitepackages,
65 | but fallback on `get_purelib()/get_platlib()` if unavailable
66 | (e.g. in a virtualenv created by virtualenv<20)
67 |
68 | Returns normalized set of strings.
69 | """
70 | if hasattr(site, "getsitepackages"):
71 | system_sites = site.getsitepackages()
72 | else:
73 | # virtualenv < 20 overwrites site.py without getsitepackages
74 | # fallback on get_purelib/get_platlib.
75 | # this is known to miss things, but shouldn't in the cases
76 | # where getsitepackages() has been removed (inside a virtualenv)
77 | system_sites = [get_purelib(), get_platlib()]
78 | return {os.path.normcase(path) for path in system_sites}
79 |
80 |
81 | class BuildEnvironment:
82 | """Creates and manages an isolated environment to install build deps"""
83 |
84 | def __init__(self) -> None:
85 | temp_dir = TempDirectory(kind=tempdir_kinds.BUILD_ENV, globally_managed=True)
86 |
87 | self._prefixes = OrderedDict(
88 | (name, _Prefix(os.path.join(temp_dir.path, name)))
89 | for name in ("normal", "overlay")
90 | )
91 |
92 | self._bin_dirs: List[str] = []
93 | self._lib_dirs: List[str] = []
94 | for prefix in reversed(list(self._prefixes.values())):
95 | self._bin_dirs.append(prefix.bin_dir)
96 | self._lib_dirs.extend(prefix.lib_dirs)
97 |
98 | # Customize site to:
99 | # - ensure .pth files are honored
100 | # - prevent access to system site packages
101 | system_sites = _get_system_sitepackages()
102 |
103 | self._site_dir = os.path.join(temp_dir.path, "site")
104 | if not os.path.exists(self._site_dir):
105 | os.mkdir(self._site_dir)
106 | with open(
107 | os.path.join(self._site_dir, "sitecustomize.py"), "w", encoding="utf-8"
108 | ) as fp:
109 | fp.write(
110 | textwrap.dedent(
111 | """
112 | import os, site, sys
113 |
114 | # First, drop system-sites related paths.
115 | original_sys_path = sys.path[:]
116 | known_paths = set()
117 | for path in {system_sites!r}:
118 | site.addsitedir(path, known_paths=known_paths)
119 | system_paths = set(
120 | os.path.normcase(path)
121 | for path in sys.path[len(original_sys_path):]
122 | )
123 | original_sys_path = [
124 | path for path in original_sys_path
125 | if os.path.normcase(path) not in system_paths
126 | ]
127 | sys.path = original_sys_path
128 |
129 | # Second, add lib directories.
130 | # ensuring .pth file are processed.
131 | for path in {lib_dirs!r}:
132 | assert not path in sys.path
133 | site.addsitedir(path)
134 | """
135 | ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)
136 | )
137 |
138 | def __enter__(self) -> None:
139 | self._save_env = {
140 | name: os.environ.get(name, None)
141 | for name in ("PATH", "PYTHONNOUSERSITE", "PYTHONPATH")
142 | }
143 |
144 | path = self._bin_dirs[:]
145 | old_path = self._save_env["PATH"]
146 | if old_path:
147 | path.extend(old_path.split(os.pathsep))
148 |
149 | pythonpath = [self._site_dir]
150 |
151 | os.environ.update(
152 | {
153 | "PATH": os.pathsep.join(path),
154 | "PYTHONNOUSERSITE": "1",
155 | "PYTHONPATH": os.pathsep.join(pythonpath),
156 | }
157 | )
158 |
159 | def __exit__(
160 | self,
161 | exc_type: Optional[Type[BaseException]],
162 | exc_val: Optional[BaseException],
163 | exc_tb: Optional[TracebackType],
164 | ) -> None:
165 | for varname, old_value in self._save_env.items():
166 | if old_value is None:
167 | os.environ.pop(varname, None)
168 | else:
169 | os.environ[varname] = old_value
170 |
171 | def check_requirements(
172 | self, reqs: Iterable[str]
173 | ) -> Tuple[Set[Tuple[str, str]], Set[str]]:
174 | """Return 2 sets:
175 | - conflicting requirements: set of (installed, wanted) reqs tuples
176 | - missing requirements: set of reqs
177 | """
178 | missing = set()
179 | conflicting = set()
180 | if reqs:
181 | env = (
182 | get_environment(self._lib_dirs)
183 | if hasattr(self, "_lib_dirs")
184 | else get_default_environment()
185 | )
186 | for req_str in reqs:
187 | req = get_requirement(req_str)
188 | # We're explicitly evaluating with an empty extra value, since build
189 | # environments are not provided any mechanism to select specific extras.
190 | if req.marker is not None and not req.marker.evaluate({"extra": ""}):
191 | continue
192 | dist = env.get_distribution(req.name)
193 | if not dist:
194 | missing.add(req_str)
195 | continue
196 | if isinstance(dist.version, Version):
197 | installed_req_str = f"{req.name}=={dist.version}"
198 | else:
199 | installed_req_str = f"{req.name}==={dist.version}"
200 | if not req.specifier.contains(dist.version, prereleases=True):
201 | conflicting.add((installed_req_str, req_str))
202 | # FIXME: Consider direct URL?
203 | return conflicting, missing
204 |
205 | def install_requirements(
206 | self,
207 | finder: "PackageFinder",
208 | requirements: Iterable[str],
209 | prefix_as_string: str,
210 | *,
211 | kind: str,
212 | ) -> None:
213 | prefix = self._prefixes[prefix_as_string]
214 | assert not prefix.setup
215 | prefix.setup = True
216 | if not requirements:
217 | return
218 | self._install_requirements(
219 | get_runnable_pip(),
220 | finder,
221 | requirements,
222 | prefix,
223 | kind=kind,
224 | )
225 |
226 | @staticmethod
227 | def _install_requirements(
228 | pip_runnable: str,
229 | finder: "PackageFinder",
230 | requirements: Iterable[str],
231 | prefix: _Prefix,
232 | *,
233 | kind: str,
234 | ) -> None:
235 | args: List[str] = [
236 | sys.executable,
237 | pip_runnable,
238 | "install",
239 | "--ignore-installed",
240 | "--no-user",
241 | "--prefix",
242 | prefix.path,
243 | "--no-warn-script-location",
244 | "--disable-pip-version-check",
245 | ]
246 | if logger.getEffectiveLevel() <= logging.DEBUG:
247 | args.append("-vv")
248 | elif logger.getEffectiveLevel() <= VERBOSE:
249 | args.append("-v")
250 | for format_control in ("no_binary", "only_binary"):
251 | formats = getattr(finder.format_control, format_control)
252 | args.extend(
253 | (
254 | "--" + format_control.replace("_", "-"),
255 | ",".join(sorted(formats or {":none:"})),
256 | )
257 | )
258 |
259 | index_urls = finder.index_urls
260 | if index_urls:
261 | args.extend(["-i", index_urls[0]])
262 | for extra_index in index_urls[1:]:
263 | args.extend(["--extra-index-url", extra_index])
264 | else:
265 | args.append("--no-index")
266 | for link in finder.find_links:
267 | args.extend(["--find-links", link])
268 |
269 | for host in finder.trusted_hosts:
270 | args.extend(["--trusted-host", host])
271 | if finder.allow_all_prereleases:
272 | args.append("--pre")
273 | if finder.prefer_binary:
274 | args.append("--prefer-binary")
275 | args.append("--")
276 | args.extend(requirements)
277 | extra_environ = {"_PIP_STANDALONE_CERT": where()}
278 | with open_spinner(f"Installing {kind}") as spinner:
279 | call_subprocess(
280 | args,
281 | command_desc=f"pip subprocess to install {kind}",
282 | spinner=spinner,
283 | extra_environ=extra_environ,
284 | )
285 |
286 |
287 | class NoOpBuildEnvironment(BuildEnvironment):
288 | """A no-op drop-in replacement for BuildEnvironment"""
289 |
290 | def __init__(self) -> None:
291 | pass
292 |
293 | def __enter__(self) -> None:
294 | pass
295 |
296 | def __exit__(
297 | self,
298 | exc_type: Optional[Type[BaseException]],
299 | exc_val: Optional[BaseException],
300 | exc_tb: Optional[TracebackType],
301 | ) -> None:
302 | pass
303 |
304 | def cleanup(self) -> None:
305 | pass
306 |
307 | def install_requirements(
308 | self,
309 | finder: "PackageFinder",
310 | requirements: Iterable[str],
311 | prefix_as_string: str,
312 | *,
313 | kind: str,
314 | ) -> None:
315 | raise NotImplementedError()
316 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/truststore/_api.py:
--------------------------------------------------------------------------------
```python
1 | import os
2 | import platform
3 | import socket
4 | import ssl
5 | import sys
6 | import typing
7 |
8 | import _ssl # type: ignore[import-not-found]
9 |
10 | from ._ssl_constants import (
11 | _original_SSLContext,
12 | _original_super_SSLContext,
13 | _truststore_SSLContext_dunder_class,
14 | _truststore_SSLContext_super_class,
15 | )
16 |
17 | if platform.system() == "Windows":
18 | from ._windows import _configure_context, _verify_peercerts_impl
19 | elif platform.system() == "Darwin":
20 | from ._macos import _configure_context, _verify_peercerts_impl
21 | else:
22 | from ._openssl import _configure_context, _verify_peercerts_impl
23 |
24 | if typing.TYPE_CHECKING:
25 | from pip._vendor.typing_extensions import Buffer
26 |
27 | # From typeshed/stdlib/ssl.pyi
28 | _StrOrBytesPath: typing.TypeAlias = str | bytes | os.PathLike[str] | os.PathLike[bytes]
29 | _PasswordType: typing.TypeAlias = str | bytes | typing.Callable[[], str | bytes]
30 |
31 |
32 | def inject_into_ssl() -> None:
33 | """Injects the :class:`truststore.SSLContext` into the ``ssl``
34 | module by replacing :class:`ssl.SSLContext`.
35 | """
36 | setattr(ssl, "SSLContext", SSLContext)
37 | # urllib3 holds on to its own reference of ssl.SSLContext
38 | # so we need to replace that reference too.
39 | try:
40 | import pip._vendor.urllib3.util.ssl_ as urllib3_ssl
41 |
42 | setattr(urllib3_ssl, "SSLContext", SSLContext)
43 | except ImportError:
44 | pass
45 |
46 |
47 | def extract_from_ssl() -> None:
48 | """Restores the :class:`ssl.SSLContext` class to its original state"""
49 | setattr(ssl, "SSLContext", _original_SSLContext)
50 | try:
51 | import pip._vendor.urllib3.util.ssl_ as urllib3_ssl
52 |
53 | urllib3_ssl.SSLContext = _original_SSLContext # type: ignore[assignment]
54 | except ImportError:
55 | pass
56 |
57 |
58 | class SSLContext(_truststore_SSLContext_super_class): # type: ignore[misc]
59 | """SSLContext API that uses system certificates on all platforms"""
60 |
61 | @property # type: ignore[misc]
62 | def __class__(self) -> type:
63 | # Dirty hack to get around isinstance() checks
64 | # for ssl.SSLContext instances in aiohttp/trustme
65 | # when using non-CPython implementations.
66 | return _truststore_SSLContext_dunder_class or SSLContext
67 |
68 | def __init__(self, protocol: int = None) -> None: # type: ignore[assignment]
69 | self._ctx = _original_SSLContext(protocol)
70 |
71 | class TruststoreSSLObject(ssl.SSLObject):
72 | # This object exists because wrap_bio() doesn't
73 | # immediately do the handshake so we need to do
74 | # certificate verifications after SSLObject.do_handshake()
75 |
76 | def do_handshake(self) -> None:
77 | ret = super().do_handshake()
78 | _verify_peercerts(self, server_hostname=self.server_hostname)
79 | return ret
80 |
81 | self._ctx.sslobject_class = TruststoreSSLObject
82 |
83 | def wrap_socket(
84 | self,
85 | sock: socket.socket,
86 | server_side: bool = False,
87 | do_handshake_on_connect: bool = True,
88 | suppress_ragged_eofs: bool = True,
89 | server_hostname: str | None = None,
90 | session: ssl.SSLSession | None = None,
91 | ) -> ssl.SSLSocket:
92 | # Use a context manager here because the
93 | # inner SSLContext holds on to our state
94 | # but also does the actual handshake.
95 | with _configure_context(self._ctx):
96 | ssl_sock = self._ctx.wrap_socket(
97 | sock,
98 | server_side=server_side,
99 | server_hostname=server_hostname,
100 | do_handshake_on_connect=do_handshake_on_connect,
101 | suppress_ragged_eofs=suppress_ragged_eofs,
102 | session=session,
103 | )
104 | try:
105 | _verify_peercerts(ssl_sock, server_hostname=server_hostname)
106 | except Exception:
107 | ssl_sock.close()
108 | raise
109 | return ssl_sock
110 |
111 | def wrap_bio(
112 | self,
113 | incoming: ssl.MemoryBIO,
114 | outgoing: ssl.MemoryBIO,
115 | server_side: bool = False,
116 | server_hostname: str | None = None,
117 | session: ssl.SSLSession | None = None,
118 | ) -> ssl.SSLObject:
119 | with _configure_context(self._ctx):
120 | ssl_obj = self._ctx.wrap_bio(
121 | incoming,
122 | outgoing,
123 | server_hostname=server_hostname,
124 | server_side=server_side,
125 | session=session,
126 | )
127 | return ssl_obj
128 |
129 | def load_verify_locations(
130 | self,
131 | cafile: str | bytes | os.PathLike[str] | os.PathLike[bytes] | None = None,
132 | capath: str | bytes | os.PathLike[str] | os.PathLike[bytes] | None = None,
133 | cadata: typing.Union[str, "Buffer", None] = None,
134 | ) -> None:
135 | return self._ctx.load_verify_locations(
136 | cafile=cafile, capath=capath, cadata=cadata
137 | )
138 |
139 | def load_cert_chain(
140 | self,
141 | certfile: _StrOrBytesPath,
142 | keyfile: _StrOrBytesPath | None = None,
143 | password: _PasswordType | None = None,
144 | ) -> None:
145 | return self._ctx.load_cert_chain(
146 | certfile=certfile, keyfile=keyfile, password=password
147 | )
148 |
149 | def load_default_certs(
150 | self, purpose: ssl.Purpose = ssl.Purpose.SERVER_AUTH
151 | ) -> None:
152 | return self._ctx.load_default_certs(purpose)
153 |
154 | def set_alpn_protocols(self, alpn_protocols: typing.Iterable[str]) -> None:
155 | return self._ctx.set_alpn_protocols(alpn_protocols)
156 |
157 | def set_npn_protocols(self, npn_protocols: typing.Iterable[str]) -> None:
158 | return self._ctx.set_npn_protocols(npn_protocols)
159 |
160 | def set_ciphers(self, __cipherlist: str) -> None:
161 | return self._ctx.set_ciphers(__cipherlist)
162 |
163 | def get_ciphers(self) -> typing.Any:
164 | return self._ctx.get_ciphers()
165 |
166 | def session_stats(self) -> dict[str, int]:
167 | return self._ctx.session_stats()
168 |
169 | def cert_store_stats(self) -> dict[str, int]:
170 | raise NotImplementedError()
171 |
172 | @typing.overload
173 | def get_ca_certs(
174 | self, binary_form: typing.Literal[False] = ...
175 | ) -> list[typing.Any]: ...
176 |
177 | @typing.overload
178 | def get_ca_certs(self, binary_form: typing.Literal[True] = ...) -> list[bytes]: ...
179 |
180 | @typing.overload
181 | def get_ca_certs(self, binary_form: bool = ...) -> typing.Any: ...
182 |
183 | def get_ca_certs(self, binary_form: bool = False) -> list[typing.Any] | list[bytes]:
184 | raise NotImplementedError()
185 |
186 | @property
187 | def check_hostname(self) -> bool:
188 | return self._ctx.check_hostname
189 |
190 | @check_hostname.setter
191 | def check_hostname(self, value: bool) -> None:
192 | self._ctx.check_hostname = value
193 |
194 | @property
195 | def hostname_checks_common_name(self) -> bool:
196 | return self._ctx.hostname_checks_common_name
197 |
198 | @hostname_checks_common_name.setter
199 | def hostname_checks_common_name(self, value: bool) -> None:
200 | self._ctx.hostname_checks_common_name = value
201 |
202 | @property
203 | def keylog_filename(self) -> str:
204 | return self._ctx.keylog_filename
205 |
206 | @keylog_filename.setter
207 | def keylog_filename(self, value: str) -> None:
208 | self._ctx.keylog_filename = value
209 |
210 | @property
211 | def maximum_version(self) -> ssl.TLSVersion:
212 | return self._ctx.maximum_version
213 |
214 | @maximum_version.setter
215 | def maximum_version(self, value: ssl.TLSVersion) -> None:
216 | _original_super_SSLContext.maximum_version.__set__( # type: ignore[attr-defined]
217 | self._ctx, value
218 | )
219 |
220 | @property
221 | def minimum_version(self) -> ssl.TLSVersion:
222 | return self._ctx.minimum_version
223 |
224 | @minimum_version.setter
225 | def minimum_version(self, value: ssl.TLSVersion) -> None:
226 | _original_super_SSLContext.minimum_version.__set__( # type: ignore[attr-defined]
227 | self._ctx, value
228 | )
229 |
230 | @property
231 | def options(self) -> ssl.Options:
232 | return self._ctx.options
233 |
234 | @options.setter
235 | def options(self, value: ssl.Options) -> None:
236 | _original_super_SSLContext.options.__set__( # type: ignore[attr-defined]
237 | self._ctx, value
238 | )
239 |
240 | @property
241 | def post_handshake_auth(self) -> bool:
242 | return self._ctx.post_handshake_auth
243 |
244 | @post_handshake_auth.setter
245 | def post_handshake_auth(self, value: bool) -> None:
246 | self._ctx.post_handshake_auth = value
247 |
248 | @property
249 | def protocol(self) -> ssl._SSLMethod:
250 | return self._ctx.protocol
251 |
252 | @property
253 | def security_level(self) -> int:
254 | return self._ctx.security_level
255 |
256 | @property
257 | def verify_flags(self) -> ssl.VerifyFlags:
258 | return self._ctx.verify_flags
259 |
260 | @verify_flags.setter
261 | def verify_flags(self, value: ssl.VerifyFlags) -> None:
262 | _original_super_SSLContext.verify_flags.__set__( # type: ignore[attr-defined]
263 | self._ctx, value
264 | )
265 |
266 | @property
267 | def verify_mode(self) -> ssl.VerifyMode:
268 | return self._ctx.verify_mode
269 |
270 | @verify_mode.setter
271 | def verify_mode(self, value: ssl.VerifyMode) -> None:
272 | _original_super_SSLContext.verify_mode.__set__( # type: ignore[attr-defined]
273 | self._ctx, value
274 | )
275 |
276 |
277 | # Python 3.13+ makes get_unverified_chain() a public API that only returns DER
278 | # encoded certificates. We detect whether we need to call public_bytes() for 3.10->3.12
279 | # Pre-3.13 returned None instead of an empty list from get_unverified_chain()
280 | if sys.version_info >= (3, 13):
281 |
282 | def _get_unverified_chain_bytes(sslobj: ssl.SSLObject) -> list[bytes]:
283 | unverified_chain = sslobj.get_unverified_chain() or () # type: ignore[attr-defined]
284 | return [
285 | cert if isinstance(cert, bytes) else cert.public_bytes(_ssl.ENCODING_DER)
286 | for cert in unverified_chain
287 | ]
288 |
289 | else:
290 |
291 | def _get_unverified_chain_bytes(sslobj: ssl.SSLObject) -> list[bytes]:
292 | unverified_chain = sslobj.get_unverified_chain() or () # type: ignore[attr-defined]
293 | return [cert.public_bytes(_ssl.ENCODING_DER) for cert in unverified_chain]
294 |
295 |
296 | def _verify_peercerts(
297 | sock_or_sslobj: ssl.SSLSocket | ssl.SSLObject, server_hostname: str | None
298 | ) -> None:
299 | """
300 | Verifies the peer certificates from an SSLSocket or SSLObject
301 | against the certificates in the OS trust store.
302 | """
303 | sslobj: ssl.SSLObject = sock_or_sslobj # type: ignore[assignment]
304 | try:
305 | while not hasattr(sslobj, "get_unverified_chain"):
306 | sslobj = sslobj._sslobj # type: ignore[attr-defined]
307 | except AttributeError:
308 | pass
309 |
310 | cert_bytes = _get_unverified_chain_bytes(sslobj)
311 | _verify_peercerts_impl(
312 | sock_or_sslobj.context, cert_bytes, server_hostname=server_hostname
313 | )
314 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/metadata/pkg_resources.py:
--------------------------------------------------------------------------------
```python
1 | import email.message
2 | import email.parser
3 | import logging
4 | import os
5 | import zipfile
6 | from typing import (
7 | Collection,
8 | Iterable,
9 | Iterator,
10 | List,
11 | Mapping,
12 | NamedTuple,
13 | Optional,
14 | )
15 |
16 | from pip._vendor import pkg_resources
17 | from pip._vendor.packaging.requirements import Requirement
18 | from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
19 | from pip._vendor.packaging.version import Version
20 | from pip._vendor.packaging.version import parse as parse_version
21 |
22 | from pip._internal.exceptions import InvalidWheel, NoneMetadataError, UnsupportedWheel
23 | from pip._internal.utils.egg_link import egg_link_path_from_location
24 | from pip._internal.utils.misc import display_path, normalize_path
25 | from pip._internal.utils.wheel import parse_wheel, read_wheel_metadata_file
26 |
27 | from .base import (
28 | BaseDistribution,
29 | BaseEntryPoint,
30 | BaseEnvironment,
31 | InfoPath,
32 | Wheel,
33 | )
34 |
35 | __all__ = ["NAME", "Distribution", "Environment"]
36 |
37 | logger = logging.getLogger(__name__)
38 |
39 | NAME = "pkg_resources"
40 |
41 |
42 | class EntryPoint(NamedTuple):
43 | name: str
44 | value: str
45 | group: str
46 |
47 |
48 | class InMemoryMetadata:
49 | """IMetadataProvider that reads metadata files from a dictionary.
50 |
51 | This also maps metadata decoding exceptions to our internal exception type.
52 | """
53 |
54 | def __init__(self, metadata: Mapping[str, bytes], wheel_name: str) -> None:
55 | self._metadata = metadata
56 | self._wheel_name = wheel_name
57 |
58 | def has_metadata(self, name: str) -> bool:
59 | return name in self._metadata
60 |
61 | def get_metadata(self, name: str) -> str:
62 | try:
63 | return self._metadata[name].decode()
64 | except UnicodeDecodeError as e:
65 | # Augment the default error with the origin of the file.
66 | raise UnsupportedWheel(
67 | f"Error decoding metadata for {self._wheel_name}: {e} in {name} file"
68 | )
69 |
70 | def get_metadata_lines(self, name: str) -> Iterable[str]:
71 | return pkg_resources.yield_lines(self.get_metadata(name))
72 |
73 | def metadata_isdir(self, name: str) -> bool:
74 | return False
75 |
76 | def metadata_listdir(self, name: str) -> List[str]:
77 | return []
78 |
79 | def run_script(self, script_name: str, namespace: str) -> None:
80 | pass
81 |
82 |
83 | class Distribution(BaseDistribution):
84 | def __init__(self, dist: pkg_resources.Distribution) -> None:
85 | self._dist = dist
86 | # This is populated lazily, to avoid loading metadata for all possible
87 | # distributions eagerly.
88 | self.__extra_mapping: Optional[Mapping[NormalizedName, str]] = None
89 |
90 | @property
91 | def _extra_mapping(self) -> Mapping[NormalizedName, str]:
92 | if self.__extra_mapping is None:
93 | self.__extra_mapping = {
94 | canonicalize_name(extra): extra for extra in self._dist.extras
95 | }
96 |
97 | return self.__extra_mapping
98 |
99 | @classmethod
100 | def from_directory(cls, directory: str) -> BaseDistribution:
101 | dist_dir = directory.rstrip(os.sep)
102 |
103 | # Build a PathMetadata object, from path to metadata. :wink:
104 | base_dir, dist_dir_name = os.path.split(dist_dir)
105 | metadata = pkg_resources.PathMetadata(base_dir, dist_dir)
106 |
107 | # Determine the correct Distribution object type.
108 | if dist_dir.endswith(".egg-info"):
109 | dist_cls = pkg_resources.Distribution
110 | dist_name = os.path.splitext(dist_dir_name)[0]
111 | else:
112 | assert dist_dir.endswith(".dist-info")
113 | dist_cls = pkg_resources.DistInfoDistribution
114 | dist_name = os.path.splitext(dist_dir_name)[0].split("-")[0]
115 |
116 | dist = dist_cls(base_dir, project_name=dist_name, metadata=metadata)
117 | return cls(dist)
118 |
119 | @classmethod
120 | def from_metadata_file_contents(
121 | cls,
122 | metadata_contents: bytes,
123 | filename: str,
124 | project_name: str,
125 | ) -> BaseDistribution:
126 | metadata_dict = {
127 | "METADATA": metadata_contents,
128 | }
129 | dist = pkg_resources.DistInfoDistribution(
130 | location=filename,
131 | metadata=InMemoryMetadata(metadata_dict, filename),
132 | project_name=project_name,
133 | )
134 | return cls(dist)
135 |
136 | @classmethod
137 | def from_wheel(cls, wheel: Wheel, name: str) -> BaseDistribution:
138 | try:
139 | with wheel.as_zipfile() as zf:
140 | info_dir, _ = parse_wheel(zf, name)
141 | metadata_dict = {
142 | path.split("/", 1)[-1]: read_wheel_metadata_file(zf, path)
143 | for path in zf.namelist()
144 | if path.startswith(f"{info_dir}/")
145 | }
146 | except zipfile.BadZipFile as e:
147 | raise InvalidWheel(wheel.location, name) from e
148 | except UnsupportedWheel as e:
149 | raise UnsupportedWheel(f"{name} has an invalid wheel, {e}")
150 | dist = pkg_resources.DistInfoDistribution(
151 | location=wheel.location,
152 | metadata=InMemoryMetadata(metadata_dict, wheel.location),
153 | project_name=name,
154 | )
155 | return cls(dist)
156 |
157 | @property
158 | def location(self) -> Optional[str]:
159 | return self._dist.location
160 |
161 | @property
162 | def installed_location(self) -> Optional[str]:
163 | egg_link = egg_link_path_from_location(self.raw_name)
164 | if egg_link:
165 | location = egg_link
166 | elif self.location:
167 | location = self.location
168 | else:
169 | return None
170 | return normalize_path(location)
171 |
172 | @property
173 | def info_location(self) -> Optional[str]:
174 | return self._dist.egg_info
175 |
176 | @property
177 | def installed_by_distutils(self) -> bool:
178 | # A distutils-installed distribution is provided by FileMetadata. This
179 | # provider has a "path" attribute not present anywhere else. Not the
180 | # best introspection logic, but pip has been doing this for a long time.
181 | try:
182 | return bool(self._dist._provider.path)
183 | except AttributeError:
184 | return False
185 |
186 | @property
187 | def canonical_name(self) -> NormalizedName:
188 | return canonicalize_name(self._dist.project_name)
189 |
190 | @property
191 | def version(self) -> Version:
192 | return parse_version(self._dist.version)
193 |
194 | @property
195 | def raw_version(self) -> str:
196 | return self._dist.version
197 |
198 | def is_file(self, path: InfoPath) -> bool:
199 | return self._dist.has_metadata(str(path))
200 |
201 | def iter_distutils_script_names(self) -> Iterator[str]:
202 | yield from self._dist.metadata_listdir("scripts")
203 |
204 | def read_text(self, path: InfoPath) -> str:
205 | name = str(path)
206 | if not self._dist.has_metadata(name):
207 | raise FileNotFoundError(name)
208 | content = self._dist.get_metadata(name)
209 | if content is None:
210 | raise NoneMetadataError(self, name)
211 | return content
212 |
213 | def iter_entry_points(self) -> Iterable[BaseEntryPoint]:
214 | for group, entries in self._dist.get_entry_map().items():
215 | for name, entry_point in entries.items():
216 | name, _, value = str(entry_point).partition("=")
217 | yield EntryPoint(name=name.strip(), value=value.strip(), group=group)
218 |
219 | def _metadata_impl(self) -> email.message.Message:
220 | """
221 | :raises NoneMetadataError: if the distribution reports `has_metadata()`
222 | True but `get_metadata()` returns None.
223 | """
224 | if isinstance(self._dist, pkg_resources.DistInfoDistribution):
225 | metadata_name = "METADATA"
226 | else:
227 | metadata_name = "PKG-INFO"
228 | try:
229 | metadata = self.read_text(metadata_name)
230 | except FileNotFoundError:
231 | if self.location:
232 | displaying_path = display_path(self.location)
233 | else:
234 | displaying_path = repr(self.location)
235 | logger.warning("No metadata found in %s", displaying_path)
236 | metadata = ""
237 | feed_parser = email.parser.FeedParser()
238 | feed_parser.feed(metadata)
239 | return feed_parser.close()
240 |
241 | def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]:
242 | if extras:
243 | relevant_extras = set(self._extra_mapping) & set(
244 | map(canonicalize_name, extras)
245 | )
246 | extras = [self._extra_mapping[extra] for extra in relevant_extras]
247 | return self._dist.requires(extras)
248 |
249 | def iter_provided_extras(self) -> Iterable[NormalizedName]:
250 | return self._extra_mapping.keys()
251 |
252 |
253 | class Environment(BaseEnvironment):
254 | def __init__(self, ws: pkg_resources.WorkingSet) -> None:
255 | self._ws = ws
256 |
257 | @classmethod
258 | def default(cls) -> BaseEnvironment:
259 | return cls(pkg_resources.working_set)
260 |
261 | @classmethod
262 | def from_paths(cls, paths: Optional[List[str]]) -> BaseEnvironment:
263 | return cls(pkg_resources.WorkingSet(paths))
264 |
265 | def _iter_distributions(self) -> Iterator[BaseDistribution]:
266 | for dist in self._ws:
267 | yield Distribution(dist)
268 |
269 | def _search_distribution(self, name: str) -> Optional[BaseDistribution]:
270 | """Find a distribution matching the ``name`` in the environment.
271 |
272 | This searches from *all* distributions available in the environment, to
273 | match the behavior of ``pkg_resources.get_distribution()``.
274 | """
275 | canonical_name = canonicalize_name(name)
276 | for dist in self.iter_all_distributions():
277 | if dist.canonical_name == canonical_name:
278 | return dist
279 | return None
280 |
281 | def get_distribution(self, name: str) -> Optional[BaseDistribution]:
282 | # Search the distribution by looking through the working set.
283 | dist = self._search_distribution(name)
284 | if dist:
285 | return dist
286 |
287 | # If distribution could not be found, call working_set.require to
288 | # update the working set, and try to find the distribution again.
289 | # This might happen for e.g. when you install a package twice, once
290 | # using setup.py develop and again using setup.py install. Now when
291 | # running pip uninstall twice, the package gets removed from the
292 | # working set in the first uninstall, so we have to populate the
293 | # working set again so that pip knows about it and the packages gets
294 | # picked up and is successfully uninstalled the second time too.
295 | try:
296 | # We didn't pass in any version specifiers, so this can never
297 | # raise pkg_resources.VersionConflict.
298 | self._ws.require(name)
299 | except pkg_resources.DistributionNotFound:
300 | return None
301 | return self._search_distribution(name)
302 |
```