This is page 70 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/resolvelib/resolvers.py:
--------------------------------------------------------------------------------
```python
1 | import collections
2 | import itertools
3 | import operator
4 |
5 | from .providers import AbstractResolver
6 | from .structs import DirectedGraph, IteratorMapping, build_iter_view
7 |
8 | RequirementInformation = collections.namedtuple(
9 | "RequirementInformation", ["requirement", "parent"]
10 | )
11 |
12 |
13 | class ResolverException(Exception):
14 | """A base class for all exceptions raised by this module.
15 |
16 | Exceptions derived by this class should all be handled in this module. Any
17 | bubbling pass the resolver should be treated as a bug.
18 | """
19 |
20 |
21 | class RequirementsConflicted(ResolverException):
22 | def __init__(self, criterion):
23 | super(RequirementsConflicted, self).__init__(criterion)
24 | self.criterion = criterion
25 |
26 | def __str__(self):
27 | return "Requirements conflict: {}".format(
28 | ", ".join(repr(r) for r in self.criterion.iter_requirement()),
29 | )
30 |
31 |
32 | class InconsistentCandidate(ResolverException):
33 | def __init__(self, candidate, criterion):
34 | super(InconsistentCandidate, self).__init__(candidate, criterion)
35 | self.candidate = candidate
36 | self.criterion = criterion
37 |
38 | def __str__(self):
39 | return "Provided candidate {!r} does not satisfy {}".format(
40 | self.candidate,
41 | ", ".join(repr(r) for r in self.criterion.iter_requirement()),
42 | )
43 |
44 |
45 | class Criterion(object):
46 | """Representation of possible resolution results of a package.
47 |
48 | This holds three attributes:
49 |
50 | * `information` is a collection of `RequirementInformation` pairs.
51 | Each pair is a requirement contributing to this criterion, and the
52 | candidate that provides the requirement.
53 | * `incompatibilities` is a collection of all known not-to-work candidates
54 | to exclude from consideration.
55 | * `candidates` is a collection containing all possible candidates deducted
56 | from the union of contributing requirements and known incompatibilities.
57 | It should never be empty, except when the criterion is an attribute of a
58 | raised `RequirementsConflicted` (in which case it is always empty).
59 |
60 | .. note::
61 | This class is intended to be externally immutable. **Do not** mutate
62 | any of its attribute containers.
63 | """
64 |
65 | def __init__(self, candidates, information, incompatibilities):
66 | self.candidates = candidates
67 | self.information = information
68 | self.incompatibilities = incompatibilities
69 |
70 | def __repr__(self):
71 | requirements = ", ".join(
72 | "({!r}, via={!r})".format(req, parent)
73 | for req, parent in self.information
74 | )
75 | return "Criterion({})".format(requirements)
76 |
77 | def iter_requirement(self):
78 | return (i.requirement for i in self.information)
79 |
80 | def iter_parent(self):
81 | return (i.parent for i in self.information)
82 |
83 |
84 | class ResolutionError(ResolverException):
85 | pass
86 |
87 |
88 | class ResolutionImpossible(ResolutionError):
89 | def __init__(self, causes):
90 | super(ResolutionImpossible, self).__init__(causes)
91 | # causes is a list of RequirementInformation objects
92 | self.causes = causes
93 |
94 |
95 | class ResolutionTooDeep(ResolutionError):
96 | def __init__(self, round_count):
97 | super(ResolutionTooDeep, self).__init__(round_count)
98 | self.round_count = round_count
99 |
100 |
101 | # Resolution state in a round.
102 | State = collections.namedtuple("State", "mapping criteria backtrack_causes")
103 |
104 |
105 | class Resolution(object):
106 | """Stateful resolution object.
107 |
108 | This is designed as a one-off object that holds information to kick start
109 | the resolution process, and holds the results afterwards.
110 | """
111 |
112 | def __init__(self, provider, reporter):
113 | self._p = provider
114 | self._r = reporter
115 | self._states = []
116 |
117 | @property
118 | def state(self):
119 | try:
120 | return self._states[-1]
121 | except IndexError:
122 | raise AttributeError("state")
123 |
124 | def _push_new_state(self):
125 | """Push a new state into history.
126 |
127 | This new state will be used to hold resolution results of the next
128 | coming round.
129 | """
130 | base = self._states[-1]
131 | state = State(
132 | mapping=base.mapping.copy(),
133 | criteria=base.criteria.copy(),
134 | backtrack_causes=base.backtrack_causes[:],
135 | )
136 | self._states.append(state)
137 |
138 | def _add_to_criteria(self, criteria, requirement, parent):
139 | self._r.adding_requirement(requirement=requirement, parent=parent)
140 |
141 | identifier = self._p.identify(requirement_or_candidate=requirement)
142 | criterion = criteria.get(identifier)
143 | if criterion:
144 | incompatibilities = list(criterion.incompatibilities)
145 | else:
146 | incompatibilities = []
147 |
148 | matches = self._p.find_matches(
149 | identifier=identifier,
150 | requirements=IteratorMapping(
151 | criteria,
152 | operator.methodcaller("iter_requirement"),
153 | {identifier: [requirement]},
154 | ),
155 | incompatibilities=IteratorMapping(
156 | criteria,
157 | operator.attrgetter("incompatibilities"),
158 | {identifier: incompatibilities},
159 | ),
160 | )
161 |
162 | if criterion:
163 | information = list(criterion.information)
164 | information.append(RequirementInformation(requirement, parent))
165 | else:
166 | information = [RequirementInformation(requirement, parent)]
167 |
168 | criterion = Criterion(
169 | candidates=build_iter_view(matches),
170 | information=information,
171 | incompatibilities=incompatibilities,
172 | )
173 | if not criterion.candidates:
174 | raise RequirementsConflicted(criterion)
175 | criteria[identifier] = criterion
176 |
177 | def _remove_information_from_criteria(self, criteria, parents):
178 | """Remove information from parents of criteria.
179 |
180 | Concretely, removes all values from each criterion's ``information``
181 | field that have one of ``parents`` as provider of the requirement.
182 |
183 | :param criteria: The criteria to update.
184 | :param parents: Identifiers for which to remove information from all criteria.
185 | """
186 | if not parents:
187 | return
188 | for key, criterion in criteria.items():
189 | criteria[key] = Criterion(
190 | criterion.candidates,
191 | [
192 | information
193 | for information in criterion.information
194 | if (
195 | information.parent is None
196 | or self._p.identify(information.parent) not in parents
197 | )
198 | ],
199 | criterion.incompatibilities,
200 | )
201 |
202 | def _get_preference(self, name):
203 | return self._p.get_preference(
204 | identifier=name,
205 | resolutions=self.state.mapping,
206 | candidates=IteratorMapping(
207 | self.state.criteria,
208 | operator.attrgetter("candidates"),
209 | ),
210 | information=IteratorMapping(
211 | self.state.criteria,
212 | operator.attrgetter("information"),
213 | ),
214 | backtrack_causes=self.state.backtrack_causes,
215 | )
216 |
217 | def _is_current_pin_satisfying(self, name, criterion):
218 | try:
219 | current_pin = self.state.mapping[name]
220 | except KeyError:
221 | return False
222 | return all(
223 | self._p.is_satisfied_by(requirement=r, candidate=current_pin)
224 | for r in criterion.iter_requirement()
225 | )
226 |
227 | def _get_updated_criteria(self, candidate):
228 | criteria = self.state.criteria.copy()
229 | for requirement in self._p.get_dependencies(candidate=candidate):
230 | self._add_to_criteria(criteria, requirement, parent=candidate)
231 | return criteria
232 |
233 | def _attempt_to_pin_criterion(self, name):
234 | criterion = self.state.criteria[name]
235 |
236 | causes = []
237 | for candidate in criterion.candidates:
238 | try:
239 | criteria = self._get_updated_criteria(candidate)
240 | except RequirementsConflicted as e:
241 | self._r.rejecting_candidate(e.criterion, candidate)
242 | causes.append(e.criterion)
243 | continue
244 |
245 | # Check the newly-pinned candidate actually works. This should
246 | # always pass under normal circumstances, but in the case of a
247 | # faulty provider, we will raise an error to notify the implementer
248 | # to fix find_matches() and/or is_satisfied_by().
249 | satisfied = all(
250 | self._p.is_satisfied_by(requirement=r, candidate=candidate)
251 | for r in criterion.iter_requirement()
252 | )
253 | if not satisfied:
254 | raise InconsistentCandidate(candidate, criterion)
255 |
256 | self._r.pinning(candidate=candidate)
257 | self.state.criteria.update(criteria)
258 |
259 | # Put newly-pinned candidate at the end. This is essential because
260 | # backtracking looks at this mapping to get the last pin.
261 | self.state.mapping.pop(name, None)
262 | self.state.mapping[name] = candidate
263 |
264 | return []
265 |
266 | # All candidates tried, nothing works. This criterion is a dead
267 | # end, signal for backtracking.
268 | return causes
269 |
270 | def _backjump(self, causes):
271 | """Perform backjumping.
272 |
273 | When we enter here, the stack is like this::
274 |
275 | [ state Z ]
276 | [ state Y ]
277 | [ state X ]
278 | .... earlier states are irrelevant.
279 |
280 | 1. No pins worked for Z, so it does not have a pin.
281 | 2. We want to reset state Y to unpinned, and pin another candidate.
282 | 3. State X holds what state Y was before the pin, but does not
283 | have the incompatibility information gathered in state Y.
284 |
285 | Each iteration of the loop will:
286 |
287 | 1. Identify Z. The incompatibility is not always caused by the latest
288 | state. For example, given three requirements A, B and C, with
289 | dependencies A1, B1 and C1, where A1 and B1 are incompatible: the
290 | last state might be related to C, so we want to discard the
291 | previous state.
292 | 2. Discard Z.
293 | 3. Discard Y but remember its incompatibility information gathered
294 | previously, and the failure we're dealing with right now.
295 | 4. Push a new state Y' based on X, and apply the incompatibility
296 | information from Y to Y'.
297 | 5a. If this causes Y' to conflict, we need to backtrack again. Make Y'
298 | the new Z and go back to step 2.
299 | 5b. If the incompatibilities apply cleanly, end backtracking.
300 | """
301 | incompatible_reqs = itertools.chain(
302 | (c.parent for c in causes if c.parent is not None),
303 | (c.requirement for c in causes),
304 | )
305 | incompatible_deps = {self._p.identify(r) for r in incompatible_reqs}
306 | while len(self._states) >= 3:
307 | # Remove the state that triggered backtracking.
308 | del self._states[-1]
309 |
310 | # Ensure to backtrack to a state that caused the incompatibility
311 | incompatible_state = False
312 | while not incompatible_state:
313 | # Retrieve the last candidate pin and known incompatibilities.
314 | try:
315 | broken_state = self._states.pop()
316 | name, candidate = broken_state.mapping.popitem()
317 | except (IndexError, KeyError):
318 | raise ResolutionImpossible(causes)
319 | current_dependencies = {
320 | self._p.identify(d)
321 | for d in self._p.get_dependencies(candidate)
322 | }
323 | incompatible_state = not current_dependencies.isdisjoint(
324 | incompatible_deps
325 | )
326 |
327 | incompatibilities_from_broken = [
328 | (k, list(v.incompatibilities))
329 | for k, v in broken_state.criteria.items()
330 | ]
331 |
332 | # Also mark the newly known incompatibility.
333 | incompatibilities_from_broken.append((name, [candidate]))
334 |
335 | # Create a new state from the last known-to-work one, and apply
336 | # the previously gathered incompatibility information.
337 | def _patch_criteria():
338 | for k, incompatibilities in incompatibilities_from_broken:
339 | if not incompatibilities:
340 | continue
341 | try:
342 | criterion = self.state.criteria[k]
343 | except KeyError:
344 | continue
345 | matches = self._p.find_matches(
346 | identifier=k,
347 | requirements=IteratorMapping(
348 | self.state.criteria,
349 | operator.methodcaller("iter_requirement"),
350 | ),
351 | incompatibilities=IteratorMapping(
352 | self.state.criteria,
353 | operator.attrgetter("incompatibilities"),
354 | {k: incompatibilities},
355 | ),
356 | )
357 | candidates = build_iter_view(matches)
358 | if not candidates:
359 | return False
360 | incompatibilities.extend(criterion.incompatibilities)
361 | self.state.criteria[k] = Criterion(
362 | candidates=candidates,
363 | information=list(criterion.information),
364 | incompatibilities=incompatibilities,
365 | )
366 | return True
367 |
368 | self._push_new_state()
369 | success = _patch_criteria()
370 |
371 | # It works! Let's work on this new state.
372 | if success:
373 | return True
374 |
375 | # State does not work after applying known incompatibilities.
376 | # Try the still previous state.
377 |
378 | # No way to backtrack anymore.
379 | return False
380 |
381 | def resolve(self, requirements, max_rounds):
382 | if self._states:
383 | raise RuntimeError("already resolved")
384 |
385 | self._r.starting()
386 |
387 | # Initialize the root state.
388 | self._states = [
389 | State(
390 | mapping=collections.OrderedDict(),
391 | criteria={},
392 | backtrack_causes=[],
393 | )
394 | ]
395 | for r in requirements:
396 | try:
397 | self._add_to_criteria(self.state.criteria, r, parent=None)
398 | except RequirementsConflicted as e:
399 | raise ResolutionImpossible(e.criterion.information)
400 |
401 | # The root state is saved as a sentinel so the first ever pin can have
402 | # something to backtrack to if it fails. The root state is basically
403 | # pinning the virtual "root" package in the graph.
404 | self._push_new_state()
405 |
406 | for round_index in range(max_rounds):
407 | self._r.starting_round(index=round_index)
408 |
409 | unsatisfied_names = [
410 | key
411 | for key, criterion in self.state.criteria.items()
412 | if not self._is_current_pin_satisfying(key, criterion)
413 | ]
414 |
415 | # All criteria are accounted for. Nothing more to pin, we are done!
416 | if not unsatisfied_names:
417 | self._r.ending(state=self.state)
418 | return self.state
419 |
420 | # keep track of satisfied names to calculate diff after pinning
421 | satisfied_names = set(self.state.criteria.keys()) - set(
422 | unsatisfied_names
423 | )
424 |
425 | # Choose the most preferred unpinned criterion to try.
426 | name = min(unsatisfied_names, key=self._get_preference)
427 | failure_causes = self._attempt_to_pin_criterion(name)
428 |
429 | if failure_causes:
430 | causes = [i for c in failure_causes for i in c.information]
431 | # Backjump if pinning fails. The backjump process puts us in
432 | # an unpinned state, so we can work on it in the next round.
433 | self._r.resolving_conflicts(causes=causes)
434 | success = self._backjump(causes)
435 | self.state.backtrack_causes[:] = causes
436 |
437 | # Dead ends everywhere. Give up.
438 | if not success:
439 | raise ResolutionImpossible(self.state.backtrack_causes)
440 | else:
441 | # discard as information sources any invalidated names
442 | # (unsatisfied names that were previously satisfied)
443 | newly_unsatisfied_names = {
444 | key
445 | for key, criterion in self.state.criteria.items()
446 | if key in satisfied_names
447 | and not self._is_current_pin_satisfying(key, criterion)
448 | }
449 | self._remove_information_from_criteria(
450 | self.state.criteria, newly_unsatisfied_names
451 | )
452 | # Pinning was successful. Push a new state to do another pin.
453 | self._push_new_state()
454 |
455 | self._r.ending_round(index=round_index, state=self.state)
456 |
457 | raise ResolutionTooDeep(max_rounds)
458 |
459 |
460 | def _has_route_to_root(criteria, key, all_keys, connected):
461 | if key in connected:
462 | return True
463 | if key not in criteria:
464 | return False
465 | for p in criteria[key].iter_parent():
466 | try:
467 | pkey = all_keys[id(p)]
468 | except KeyError:
469 | continue
470 | if pkey in connected:
471 | connected.add(key)
472 | return True
473 | if _has_route_to_root(criteria, pkey, all_keys, connected):
474 | connected.add(key)
475 | return True
476 | return False
477 |
478 |
479 | Result = collections.namedtuple("Result", "mapping graph criteria")
480 |
481 |
482 | def _build_result(state):
483 | mapping = state.mapping
484 | all_keys = {id(v): k for k, v in mapping.items()}
485 | all_keys[id(None)] = None
486 |
487 | graph = DirectedGraph()
488 | graph.add(None) # Sentinel as root dependencies' parent.
489 |
490 | connected = {None}
491 | for key, criterion in state.criteria.items():
492 | if not _has_route_to_root(state.criteria, key, all_keys, connected):
493 | continue
494 | if key not in graph:
495 | graph.add(key)
496 | for p in criterion.iter_parent():
497 | try:
498 | pkey = all_keys[id(p)]
499 | except KeyError:
500 | continue
501 | if pkey not in graph:
502 | graph.add(pkey)
503 | graph.connect(pkey, key)
504 |
505 | return Result(
506 | mapping={k: v for k, v in mapping.items() if k in connected},
507 | graph=graph,
508 | criteria=state.criteria,
509 | )
510 |
511 |
512 | class Resolver(AbstractResolver):
513 | """The thing that performs the actual resolution work."""
514 |
515 | base_exception = ResolverException
516 |
517 | def resolve(self, requirements, max_rounds=100):
518 | """Take a collection of constraints, spit out the resolution result.
519 |
520 | The return value is a representation to the final resolution result. It
521 | is a tuple subclass with three public members:
522 |
523 | * `mapping`: A dict of resolved candidates. Each key is an identifier
524 | of a requirement (as returned by the provider's `identify` method),
525 | and the value is the resolved candidate.
526 | * `graph`: A `DirectedGraph` instance representing the dependency tree.
527 | The vertices are keys of `mapping`, and each edge represents *why*
528 | a particular package is included. A special vertex `None` is
529 | included to represent parents of user-supplied requirements.
530 | * `criteria`: A dict of "criteria" that hold detailed information on
531 | how edges in the graph are derived. Each key is an identifier of a
532 | requirement, and the value is a `Criterion` instance.
533 |
534 | The following exceptions may be raised if a resolution cannot be found:
535 |
536 | * `ResolutionImpossible`: A resolution cannot be found for the given
537 | combination of requirements. The `causes` attribute of the
538 | exception is a list of (requirement, parent), giving the
539 | requirements that could not be satisfied.
540 | * `ResolutionTooDeep`: The dependency tree is too deeply nested and
541 | the resolver gave up. This is usually caused by a circular
542 | dependency, but you can try to resolve this by increasing the
543 | `max_rounds` argument.
544 | """
545 | resolution = Resolution(self.provider, self.reporter)
546 | state = resolution.resolve(requirements, max_rounds=max_rounds)
547 | return _build_result(state)
548 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/lxml/includes/libxml/xmlwriter.h:
--------------------------------------------------------------------------------
```
1 | /*
2 | * Summary: text writing API for XML
3 | * Description: text writing API for XML
4 | *
5 | * Copy: See Copyright for the status of this software.
6 | *
7 | * Author: Alfred Mickautsch <[email protected]>
8 | */
9 |
10 | #ifndef __XML_XMLWRITER_H__
11 | #define __XML_XMLWRITER_H__
12 |
13 | #include <libxml/xmlversion.h>
14 |
15 | #ifdef LIBXML_WRITER_ENABLED
16 |
17 | #include <stdarg.h>
18 | #include <libxml/xmlIO.h>
19 | #include <libxml/list.h>
20 | #include <libxml/xmlstring.h>
21 |
22 | #ifdef __cplusplus
23 | extern "C" {
24 | #endif
25 |
26 | typedef struct _xmlTextWriter xmlTextWriter;
27 | typedef xmlTextWriter *xmlTextWriterPtr;
28 |
29 | /*
30 | * Constructors & Destructor
31 | */
32 | XMLPUBFUN xmlTextWriterPtr
33 | xmlNewTextWriter(xmlOutputBufferPtr out);
34 | XMLPUBFUN xmlTextWriterPtr
35 | xmlNewTextWriterFilename(const char *uri, int compression);
36 | XMLPUBFUN xmlTextWriterPtr
37 | xmlNewTextWriterMemory(xmlBufferPtr buf, int compression);
38 | XMLPUBFUN xmlTextWriterPtr
39 | xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt, int compression);
40 | XMLPUBFUN xmlTextWriterPtr
41 | xmlNewTextWriterDoc(xmlDocPtr * doc, int compression);
42 | XMLPUBFUN xmlTextWriterPtr
43 | xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node,
44 | int compression);
45 | XMLPUBFUN void xmlFreeTextWriter(xmlTextWriterPtr writer);
46 |
47 | /*
48 | * Functions
49 | */
50 |
51 |
52 | /*
53 | * Document
54 | */
55 | XMLPUBFUN int
56 | xmlTextWriterStartDocument(xmlTextWriterPtr writer,
57 | const char *version,
58 | const char *encoding,
59 | const char *standalone);
60 | XMLPUBFUN int xmlTextWriterEndDocument(xmlTextWriterPtr
61 | writer);
62 |
63 | /*
64 | * Comments
65 | */
66 | XMLPUBFUN int xmlTextWriterStartComment(xmlTextWriterPtr
67 | writer);
68 | XMLPUBFUN int xmlTextWriterEndComment(xmlTextWriterPtr writer);
69 | XMLPUBFUN int
70 | xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
71 | const char *format, ...)
72 | LIBXML_ATTR_FORMAT(2,3);
73 | XMLPUBFUN int
74 | xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
75 | const char *format,
76 | va_list argptr)
77 | LIBXML_ATTR_FORMAT(2,0);
78 | XMLPUBFUN int xmlTextWriterWriteComment(xmlTextWriterPtr
79 | writer,
80 | const xmlChar *
81 | content);
82 |
83 | /*
84 | * Elements
85 | */
86 | XMLPUBFUN int
87 | xmlTextWriterStartElement(xmlTextWriterPtr writer,
88 | const xmlChar * name);
89 | XMLPUBFUN int xmlTextWriterStartElementNS(xmlTextWriterPtr
90 | writer,
91 | const xmlChar *
92 | prefix,
93 | const xmlChar * name,
94 | const xmlChar *
95 | namespaceURI);
96 | XMLPUBFUN int xmlTextWriterEndElement(xmlTextWriterPtr writer);
97 | XMLPUBFUN int xmlTextWriterFullEndElement(xmlTextWriterPtr
98 | writer);
99 |
100 | /*
101 | * Elements conveniency functions
102 | */
103 | XMLPUBFUN int
104 | xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
105 | const xmlChar * name,
106 | const char *format, ...)
107 | LIBXML_ATTR_FORMAT(3,4);
108 | XMLPUBFUN int
109 | xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
110 | const xmlChar * name,
111 | const char *format,
112 | va_list argptr)
113 | LIBXML_ATTR_FORMAT(3,0);
114 | XMLPUBFUN int xmlTextWriterWriteElement(xmlTextWriterPtr
115 | writer,
116 | const xmlChar * name,
117 | const xmlChar *
118 | content);
119 | XMLPUBFUN int
120 | xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
121 | const xmlChar * prefix,
122 | const xmlChar * name,
123 | const xmlChar * namespaceURI,
124 | const char *format, ...)
125 | LIBXML_ATTR_FORMAT(5,6);
126 | XMLPUBFUN int
127 | xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
128 | const xmlChar * prefix,
129 | const xmlChar * name,
130 | const xmlChar * namespaceURI,
131 | const char *format,
132 | va_list argptr)
133 | LIBXML_ATTR_FORMAT(5,0);
134 | XMLPUBFUN int xmlTextWriterWriteElementNS(xmlTextWriterPtr
135 | writer,
136 | const xmlChar *
137 | prefix,
138 | const xmlChar * name,
139 | const xmlChar *
140 | namespaceURI,
141 | const xmlChar *
142 | content);
143 |
144 | /*
145 | * Text
146 | */
147 | XMLPUBFUN int
148 | xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer,
149 | const char *format, ...)
150 | LIBXML_ATTR_FORMAT(2,3);
151 | XMLPUBFUN int
152 | xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer,
153 | const char *format, va_list argptr)
154 | LIBXML_ATTR_FORMAT(2,0);
155 | XMLPUBFUN int
156 | xmlTextWriterWriteRawLen(xmlTextWriterPtr writer,
157 | const xmlChar * content, int len);
158 | XMLPUBFUN int
159 | xmlTextWriterWriteRaw(xmlTextWriterPtr writer,
160 | const xmlChar * content);
161 | XMLPUBFUN int xmlTextWriterWriteFormatString(xmlTextWriterPtr
162 | writer,
163 | const char
164 | *format, ...)
165 | LIBXML_ATTR_FORMAT(2,3);
166 | XMLPUBFUN int xmlTextWriterWriteVFormatString(xmlTextWriterPtr
167 | writer,
168 | const char
169 | *format,
170 | va_list argptr)
171 | LIBXML_ATTR_FORMAT(2,0);
172 | XMLPUBFUN int xmlTextWriterWriteString(xmlTextWriterPtr writer,
173 | const xmlChar *
174 | content);
175 | XMLPUBFUN int xmlTextWriterWriteBase64(xmlTextWriterPtr writer,
176 | const char *data,
177 | int start, int len);
178 | XMLPUBFUN int xmlTextWriterWriteBinHex(xmlTextWriterPtr writer,
179 | const char *data,
180 | int start, int len);
181 |
182 | /*
183 | * Attributes
184 | */
185 | XMLPUBFUN int
186 | xmlTextWriterStartAttribute(xmlTextWriterPtr writer,
187 | const xmlChar * name);
188 | XMLPUBFUN int xmlTextWriterStartAttributeNS(xmlTextWriterPtr
189 | writer,
190 | const xmlChar *
191 | prefix,
192 | const xmlChar *
193 | name,
194 | const xmlChar *
195 | namespaceURI);
196 | XMLPUBFUN int xmlTextWriterEndAttribute(xmlTextWriterPtr
197 | writer);
198 |
199 | /*
200 | * Attributes conveniency functions
201 | */
202 | XMLPUBFUN int
203 | xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
204 | const xmlChar * name,
205 | const char *format, ...)
206 | LIBXML_ATTR_FORMAT(3,4);
207 | XMLPUBFUN int
208 | xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
209 | const xmlChar * name,
210 | const char *format,
211 | va_list argptr)
212 | LIBXML_ATTR_FORMAT(3,0);
213 | XMLPUBFUN int xmlTextWriterWriteAttribute(xmlTextWriterPtr
214 | writer,
215 | const xmlChar * name,
216 | const xmlChar *
217 | content);
218 | XMLPUBFUN int
219 | xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
220 | const xmlChar * prefix,
221 | const xmlChar * name,
222 | const xmlChar * namespaceURI,
223 | const char *format, ...)
224 | LIBXML_ATTR_FORMAT(5,6);
225 | XMLPUBFUN int
226 | xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
227 | const xmlChar * prefix,
228 | const xmlChar * name,
229 | const xmlChar * namespaceURI,
230 | const char *format,
231 | va_list argptr)
232 | LIBXML_ATTR_FORMAT(5,0);
233 | XMLPUBFUN int xmlTextWriterWriteAttributeNS(xmlTextWriterPtr
234 | writer,
235 | const xmlChar *
236 | prefix,
237 | const xmlChar *
238 | name,
239 | const xmlChar *
240 | namespaceURI,
241 | const xmlChar *
242 | content);
243 |
244 | /*
245 | * PI's
246 | */
247 | XMLPUBFUN int
248 | xmlTextWriterStartPI(xmlTextWriterPtr writer,
249 | const xmlChar * target);
250 | XMLPUBFUN int xmlTextWriterEndPI(xmlTextWriterPtr writer);
251 |
252 | /*
253 | * PI conveniency functions
254 | */
255 | XMLPUBFUN int
256 | xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer,
257 | const xmlChar * target,
258 | const char *format, ...)
259 | LIBXML_ATTR_FORMAT(3,4);
260 | XMLPUBFUN int
261 | xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
262 | const xmlChar * target,
263 | const char *format, va_list argptr)
264 | LIBXML_ATTR_FORMAT(3,0);
265 | XMLPUBFUN int
266 | xmlTextWriterWritePI(xmlTextWriterPtr writer,
267 | const xmlChar * target,
268 | const xmlChar * content);
269 |
270 | /**
271 | * xmlTextWriterWriteProcessingInstruction:
272 | *
273 | * This macro maps to xmlTextWriterWritePI
274 | */
275 | #define xmlTextWriterWriteProcessingInstruction xmlTextWriterWritePI
276 |
277 | /*
278 | * CDATA
279 | */
280 | XMLPUBFUN int xmlTextWriterStartCDATA(xmlTextWriterPtr writer);
281 | XMLPUBFUN int xmlTextWriterEndCDATA(xmlTextWriterPtr writer);
282 |
283 | /*
284 | * CDATA conveniency functions
285 | */
286 | XMLPUBFUN int
287 | xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer,
288 | const char *format, ...)
289 | LIBXML_ATTR_FORMAT(2,3);
290 | XMLPUBFUN int
291 | xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer,
292 | const char *format, va_list argptr)
293 | LIBXML_ATTR_FORMAT(2,0);
294 | XMLPUBFUN int
295 | xmlTextWriterWriteCDATA(xmlTextWriterPtr writer,
296 | const xmlChar * content);
297 |
298 | /*
299 | * DTD
300 | */
301 | XMLPUBFUN int
302 | xmlTextWriterStartDTD(xmlTextWriterPtr writer,
303 | const xmlChar * name,
304 | const xmlChar * pubid,
305 | const xmlChar * sysid);
306 | XMLPUBFUN int xmlTextWriterEndDTD(xmlTextWriterPtr writer);
307 |
308 | /*
309 | * DTD conveniency functions
310 | */
311 | XMLPUBFUN int
312 | xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
313 | const xmlChar * name,
314 | const xmlChar * pubid,
315 | const xmlChar * sysid,
316 | const char *format, ...)
317 | LIBXML_ATTR_FORMAT(5,6);
318 | XMLPUBFUN int
319 | xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
320 | const xmlChar * name,
321 | const xmlChar * pubid,
322 | const xmlChar * sysid,
323 | const char *format, va_list argptr)
324 | LIBXML_ATTR_FORMAT(5,0);
325 | XMLPUBFUN int
326 | xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
327 | const xmlChar * name,
328 | const xmlChar * pubid,
329 | const xmlChar * sysid,
330 | const xmlChar * subset);
331 |
332 | /**
333 | * xmlTextWriterWriteDocType:
334 | *
335 | * this macro maps to xmlTextWriterWriteDTD
336 | */
337 | #define xmlTextWriterWriteDocType xmlTextWriterWriteDTD
338 |
339 | /*
340 | * DTD element definition
341 | */
342 | XMLPUBFUN int
343 | xmlTextWriterStartDTDElement(xmlTextWriterPtr writer,
344 | const xmlChar * name);
345 | XMLPUBFUN int xmlTextWriterEndDTDElement(xmlTextWriterPtr
346 | writer);
347 |
348 | /*
349 | * DTD element definition conveniency functions
350 | */
351 | XMLPUBFUN int
352 | xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
353 | const xmlChar * name,
354 | const char *format, ...)
355 | LIBXML_ATTR_FORMAT(3,4);
356 | XMLPUBFUN int
357 | xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
358 | const xmlChar * name,
359 | const char *format,
360 | va_list argptr)
361 | LIBXML_ATTR_FORMAT(3,0);
362 | XMLPUBFUN int xmlTextWriterWriteDTDElement(xmlTextWriterPtr
363 | writer,
364 | const xmlChar *
365 | name,
366 | const xmlChar *
367 | content);
368 |
369 | /*
370 | * DTD attribute list definition
371 | */
372 | XMLPUBFUN int
373 | xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer,
374 | const xmlChar * name);
375 | XMLPUBFUN int xmlTextWriterEndDTDAttlist(xmlTextWriterPtr
376 | writer);
377 |
378 | /*
379 | * DTD attribute list definition conveniency functions
380 | */
381 | XMLPUBFUN int
382 | xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
383 | const xmlChar * name,
384 | const char *format, ...)
385 | LIBXML_ATTR_FORMAT(3,4);
386 | XMLPUBFUN int
387 | xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
388 | const xmlChar * name,
389 | const char *format,
390 | va_list argptr)
391 | LIBXML_ATTR_FORMAT(3,0);
392 | XMLPUBFUN int xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr
393 | writer,
394 | const xmlChar *
395 | name,
396 | const xmlChar *
397 | content);
398 |
399 | /*
400 | * DTD entity definition
401 | */
402 | XMLPUBFUN int
403 | xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
404 | int pe, const xmlChar * name);
405 | XMLPUBFUN int xmlTextWriterEndDTDEntity(xmlTextWriterPtr
406 | writer);
407 |
408 | /*
409 | * DTD entity definition conveniency functions
410 | */
411 | XMLPUBFUN int
412 | xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
413 | int pe,
414 | const xmlChar * name,
415 | const char *format, ...)
416 | LIBXML_ATTR_FORMAT(4,5);
417 | XMLPUBFUN int
418 | xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
419 | int pe,
420 | const xmlChar * name,
421 | const char *format,
422 | va_list argptr)
423 | LIBXML_ATTR_FORMAT(4,0);
424 | XMLPUBFUN int
425 | xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
426 | int pe,
427 | const xmlChar * name,
428 | const xmlChar * content);
429 | XMLPUBFUN int
430 | xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
431 | int pe,
432 | const xmlChar * name,
433 | const xmlChar * pubid,
434 | const xmlChar * sysid,
435 | const xmlChar * ndataid);
436 | XMLPUBFUN int
437 | xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr
438 | writer,
439 | const xmlChar * pubid,
440 | const xmlChar * sysid,
441 | const xmlChar *
442 | ndataid);
443 | XMLPUBFUN int xmlTextWriterWriteDTDEntity(xmlTextWriterPtr
444 | writer, int pe,
445 | const xmlChar * name,
446 | const xmlChar *
447 | pubid,
448 | const xmlChar *
449 | sysid,
450 | const xmlChar *
451 | ndataid,
452 | const xmlChar *
453 | content);
454 |
455 | /*
456 | * DTD notation definition
457 | */
458 | XMLPUBFUN int
459 | xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
460 | const xmlChar * name,
461 | const xmlChar * pubid,
462 | const xmlChar * sysid);
463 |
464 | /*
465 | * Indentation
466 | */
467 | XMLPUBFUN int
468 | xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent);
469 | XMLPUBFUN int
470 | xmlTextWriterSetIndentString(xmlTextWriterPtr writer,
471 | const xmlChar * str);
472 |
473 | XMLPUBFUN int
474 | xmlTextWriterSetQuoteChar(xmlTextWriterPtr writer, xmlChar quotechar);
475 |
476 |
477 | /*
478 | * misc
479 | */
480 | XMLPUBFUN int xmlTextWriterFlush(xmlTextWriterPtr writer);
481 |
482 | #ifdef __cplusplus
483 | }
484 | #endif
485 |
486 | #endif /* LIBXML_WRITER_ENABLED */
487 |
488 | #endif /* __XML_XMLWRITER_H__ */
489 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/distlib/index.py:
--------------------------------------------------------------------------------
```python
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Copyright (C) 2013-2023 Vinay Sajip.
4 | # Licensed to the Python Software Foundation under a contributor agreement.
5 | # See LICENSE.txt and CONTRIBUTORS.txt.
6 | #
7 | import hashlib
8 | import logging
9 | import os
10 | import shutil
11 | import subprocess
12 | import tempfile
13 | try:
14 | from threading import Thread
15 | except ImportError: # pragma: no cover
16 | from dummy_threading import Thread
17 |
18 | from . import DistlibException
19 | from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr,
20 | urlparse, build_opener, string_types)
21 | from .util import zip_dir, ServerProxy
22 |
23 | logger = logging.getLogger(__name__)
24 |
25 | DEFAULT_INDEX = 'https://pypi.org/pypi'
26 | DEFAULT_REALM = 'pypi'
27 |
28 |
29 | class PackageIndex(object):
30 | """
31 | This class represents a package index compatible with PyPI, the Python
32 | Package Index.
33 | """
34 |
35 | boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$'
36 |
37 | def __init__(self, url=None):
38 | """
39 | Initialise an instance.
40 |
41 | :param url: The URL of the index. If not specified, the URL for PyPI is
42 | used.
43 | """
44 | self.url = url or DEFAULT_INDEX
45 | self.read_configuration()
46 | scheme, netloc, path, params, query, frag = urlparse(self.url)
47 | if params or query or frag or scheme not in ('http', 'https'):
48 | raise DistlibException('invalid repository: %s' % self.url)
49 | self.password_handler = None
50 | self.ssl_verifier = None
51 | self.gpg = None
52 | self.gpg_home = None
53 | with open(os.devnull, 'w') as sink:
54 | # Use gpg by default rather than gpg2, as gpg2 insists on
55 | # prompting for passwords
56 | for s in ('gpg', 'gpg2'):
57 | try:
58 | rc = subprocess.check_call([s, '--version'], stdout=sink,
59 | stderr=sink)
60 | if rc == 0:
61 | self.gpg = s
62 | break
63 | except OSError:
64 | pass
65 |
66 | def _get_pypirc_command(self):
67 | """
68 | Get the distutils command for interacting with PyPI configurations.
69 | :return: the command.
70 | """
71 | from .util import _get_pypirc_command as cmd
72 | return cmd()
73 |
74 | def read_configuration(self):
75 | """
76 | Read the PyPI access configuration as supported by distutils. This populates
77 | ``username``, ``password``, ``realm`` and ``url`` attributes from the
78 | configuration.
79 | """
80 | from .util import _load_pypirc
81 | cfg = _load_pypirc(self)
82 | self.username = cfg.get('username')
83 | self.password = cfg.get('password')
84 | self.realm = cfg.get('realm', 'pypi')
85 | self.url = cfg.get('repository', self.url)
86 |
87 | def save_configuration(self):
88 | """
89 | Save the PyPI access configuration. You must have set ``username`` and
90 | ``password`` attributes before calling this method.
91 | """
92 | self.check_credentials()
93 | from .util import _store_pypirc
94 | _store_pypirc(self)
95 |
96 | def check_credentials(self):
97 | """
98 | Check that ``username`` and ``password`` have been set, and raise an
99 | exception if not.
100 | """
101 | if self.username is None or self.password is None:
102 | raise DistlibException('username and password must be set')
103 | pm = HTTPPasswordMgr()
104 | _, netloc, _, _, _, _ = urlparse(self.url)
105 | pm.add_password(self.realm, netloc, self.username, self.password)
106 | self.password_handler = HTTPBasicAuthHandler(pm)
107 |
108 | def register(self, metadata): # pragma: no cover
109 | """
110 | Register a distribution on PyPI, using the provided metadata.
111 |
112 | :param metadata: A :class:`Metadata` instance defining at least a name
113 | and version number for the distribution to be
114 | registered.
115 | :return: The HTTP response received from PyPI upon submission of the
116 | request.
117 | """
118 | self.check_credentials()
119 | metadata.validate()
120 | d = metadata.todict()
121 | d[':action'] = 'verify'
122 | request = self.encode_request(d.items(), [])
123 | self.send_request(request)
124 | d[':action'] = 'submit'
125 | request = self.encode_request(d.items(), [])
126 | return self.send_request(request)
127 |
128 | def _reader(self, name, stream, outbuf):
129 | """
130 | Thread runner for reading lines of from a subprocess into a buffer.
131 |
132 | :param name: The logical name of the stream (used for logging only).
133 | :param stream: The stream to read from. This will typically a pipe
134 | connected to the output stream of a subprocess.
135 | :param outbuf: The list to append the read lines to.
136 | """
137 | while True:
138 | s = stream.readline()
139 | if not s:
140 | break
141 | s = s.decode('utf-8').rstrip()
142 | outbuf.append(s)
143 | logger.debug('%s: %s' % (name, s))
144 | stream.close()
145 |
146 | def get_sign_command(self, filename, signer, sign_password, keystore=None): # pragma: no cover
147 | """
148 | Return a suitable command for signing a file.
149 |
150 | :param filename: The pathname to the file to be signed.
151 | :param signer: The identifier of the signer of the file.
152 | :param sign_password: The passphrase for the signer's
153 | private key used for signing.
154 | :param keystore: The path to a directory which contains the keys
155 | used in verification. If not specified, the
156 | instance's ``gpg_home`` attribute is used instead.
157 | :return: The signing command as a list suitable to be
158 | passed to :class:`subprocess.Popen`.
159 | """
160 | cmd = [self.gpg, '--status-fd', '2', '--no-tty']
161 | if keystore is None:
162 | keystore = self.gpg_home
163 | if keystore:
164 | cmd.extend(['--homedir', keystore])
165 | if sign_password is not None:
166 | cmd.extend(['--batch', '--passphrase-fd', '0'])
167 | td = tempfile.mkdtemp()
168 | sf = os.path.join(td, os.path.basename(filename) + '.asc')
169 | cmd.extend(['--detach-sign', '--armor', '--local-user',
170 | signer, '--output', sf, filename])
171 | logger.debug('invoking: %s', ' '.join(cmd))
172 | return cmd, sf
173 |
174 | def run_command(self, cmd, input_data=None):
175 | """
176 | Run a command in a child process , passing it any input data specified.
177 |
178 | :param cmd: The command to run.
179 | :param input_data: If specified, this must be a byte string containing
180 | data to be sent to the child process.
181 | :return: A tuple consisting of the subprocess' exit code, a list of
182 | lines read from the subprocess' ``stdout``, and a list of
183 | lines read from the subprocess' ``stderr``.
184 | """
185 | kwargs = {
186 | 'stdout': subprocess.PIPE,
187 | 'stderr': subprocess.PIPE,
188 | }
189 | if input_data is not None:
190 | kwargs['stdin'] = subprocess.PIPE
191 | stdout = []
192 | stderr = []
193 | p = subprocess.Popen(cmd, **kwargs)
194 | # We don't use communicate() here because we may need to
195 | # get clever with interacting with the command
196 | t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout))
197 | t1.start()
198 | t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr))
199 | t2.start()
200 | if input_data is not None:
201 | p.stdin.write(input_data)
202 | p.stdin.close()
203 |
204 | p.wait()
205 | t1.join()
206 | t2.join()
207 | return p.returncode, stdout, stderr
208 |
209 | def sign_file(self, filename, signer, sign_password, keystore=None): # pragma: no cover
210 | """
211 | Sign a file.
212 |
213 | :param filename: The pathname to the file to be signed.
214 | :param signer: The identifier of the signer of the file.
215 | :param sign_password: The passphrase for the signer's
216 | private key used for signing.
217 | :param keystore: The path to a directory which contains the keys
218 | used in signing. If not specified, the instance's
219 | ``gpg_home`` attribute is used instead.
220 | :return: The absolute pathname of the file where the signature is
221 | stored.
222 | """
223 | cmd, sig_file = self.get_sign_command(filename, signer, sign_password,
224 | keystore)
225 | rc, stdout, stderr = self.run_command(cmd,
226 | sign_password.encode('utf-8'))
227 | if rc != 0:
228 | raise DistlibException('sign command failed with error '
229 | 'code %s' % rc)
230 | return sig_file
231 |
232 | def upload_file(self, metadata, filename, signer=None, sign_password=None,
233 | filetype='sdist', pyversion='source', keystore=None):
234 | """
235 | Upload a release file to the index.
236 |
237 | :param metadata: A :class:`Metadata` instance defining at least a name
238 | and version number for the file to be uploaded.
239 | :param filename: The pathname of the file to be uploaded.
240 | :param signer: The identifier of the signer of the file.
241 | :param sign_password: The passphrase for the signer's
242 | private key used for signing.
243 | :param filetype: The type of the file being uploaded. This is the
244 | distutils command which produced that file, e.g.
245 | ``sdist`` or ``bdist_wheel``.
246 | :param pyversion: The version of Python which the release relates
247 | to. For code compatible with any Python, this would
248 | be ``source``, otherwise it would be e.g. ``3.2``.
249 | :param keystore: The path to a directory which contains the keys
250 | used in signing. If not specified, the instance's
251 | ``gpg_home`` attribute is used instead.
252 | :return: The HTTP response received from PyPI upon submission of the
253 | request.
254 | """
255 | self.check_credentials()
256 | if not os.path.exists(filename):
257 | raise DistlibException('not found: %s' % filename)
258 | metadata.validate()
259 | d = metadata.todict()
260 | sig_file = None
261 | if signer:
262 | if not self.gpg:
263 | logger.warning('no signing program available - not signed')
264 | else:
265 | sig_file = self.sign_file(filename, signer, sign_password,
266 | keystore)
267 | with open(filename, 'rb') as f:
268 | file_data = f.read()
269 | md5_digest = hashlib.md5(file_data).hexdigest()
270 | sha256_digest = hashlib.sha256(file_data).hexdigest()
271 | d.update({
272 | ':action': 'file_upload',
273 | 'protocol_version': '1',
274 | 'filetype': filetype,
275 | 'pyversion': pyversion,
276 | 'md5_digest': md5_digest,
277 | 'sha256_digest': sha256_digest,
278 | })
279 | files = [('content', os.path.basename(filename), file_data)]
280 | if sig_file:
281 | with open(sig_file, 'rb') as f:
282 | sig_data = f.read()
283 | files.append(('gpg_signature', os.path.basename(sig_file),
284 | sig_data))
285 | shutil.rmtree(os.path.dirname(sig_file))
286 | request = self.encode_request(d.items(), files)
287 | return self.send_request(request)
288 |
289 | def upload_documentation(self, metadata, doc_dir): # pragma: no cover
290 | """
291 | Upload documentation to the index.
292 |
293 | :param metadata: A :class:`Metadata` instance defining at least a name
294 | and version number for the documentation to be
295 | uploaded.
296 | :param doc_dir: The pathname of the directory which contains the
297 | documentation. This should be the directory that
298 | contains the ``index.html`` for the documentation.
299 | :return: The HTTP response received from PyPI upon submission of the
300 | request.
301 | """
302 | self.check_credentials()
303 | if not os.path.isdir(doc_dir):
304 | raise DistlibException('not a directory: %r' % doc_dir)
305 | fn = os.path.join(doc_dir, 'index.html')
306 | if not os.path.exists(fn):
307 | raise DistlibException('not found: %r' % fn)
308 | metadata.validate()
309 | name, version = metadata.name, metadata.version
310 | zip_data = zip_dir(doc_dir).getvalue()
311 | fields = [(':action', 'doc_upload'),
312 | ('name', name), ('version', version)]
313 | files = [('content', name, zip_data)]
314 | request = self.encode_request(fields, files)
315 | return self.send_request(request)
316 |
317 | def get_verify_command(self, signature_filename, data_filename,
318 | keystore=None):
319 | """
320 | Return a suitable command for verifying a file.
321 |
322 | :param signature_filename: The pathname to the file containing the
323 | signature.
324 | :param data_filename: The pathname to the file containing the
325 | signed data.
326 | :param keystore: The path to a directory which contains the keys
327 | used in verification. If not specified, the
328 | instance's ``gpg_home`` attribute is used instead.
329 | :return: The verifying command as a list suitable to be
330 | passed to :class:`subprocess.Popen`.
331 | """
332 | cmd = [self.gpg, '--status-fd', '2', '--no-tty']
333 | if keystore is None:
334 | keystore = self.gpg_home
335 | if keystore:
336 | cmd.extend(['--homedir', keystore])
337 | cmd.extend(['--verify', signature_filename, data_filename])
338 | logger.debug('invoking: %s', ' '.join(cmd))
339 | return cmd
340 |
341 | def verify_signature(self, signature_filename, data_filename,
342 | keystore=None):
343 | """
344 | Verify a signature for a file.
345 |
346 | :param signature_filename: The pathname to the file containing the
347 | signature.
348 | :param data_filename: The pathname to the file containing the
349 | signed data.
350 | :param keystore: The path to a directory which contains the keys
351 | used in verification. If not specified, the
352 | instance's ``gpg_home`` attribute is used instead.
353 | :return: True if the signature was verified, else False.
354 | """
355 | if not self.gpg:
356 | raise DistlibException('verification unavailable because gpg '
357 | 'unavailable')
358 | cmd = self.get_verify_command(signature_filename, data_filename,
359 | keystore)
360 | rc, stdout, stderr = self.run_command(cmd)
361 | if rc not in (0, 1):
362 | raise DistlibException('verify command failed with error code %s' % rc)
363 | return rc == 0
364 |
365 | def download_file(self, url, destfile, digest=None, reporthook=None):
366 | """
367 | This is a convenience method for downloading a file from an URL.
368 | Normally, this will be a file from the index, though currently
369 | no check is made for this (i.e. a file can be downloaded from
370 | anywhere).
371 |
372 | The method is just like the :func:`urlretrieve` function in the
373 | standard library, except that it allows digest computation to be
374 | done during download and checking that the downloaded data
375 | matched any expected value.
376 |
377 | :param url: The URL of the file to be downloaded (assumed to be
378 | available via an HTTP GET request).
379 | :param destfile: The pathname where the downloaded file is to be
380 | saved.
381 | :param digest: If specified, this must be a (hasher, value)
382 | tuple, where hasher is the algorithm used (e.g.
383 | ``'md5'``) and ``value`` is the expected value.
384 | :param reporthook: The same as for :func:`urlretrieve` in the
385 | standard library.
386 | """
387 | if digest is None:
388 | digester = None
389 | logger.debug('No digest specified')
390 | else:
391 | if isinstance(digest, (list, tuple)):
392 | hasher, digest = digest
393 | else:
394 | hasher = 'md5'
395 | digester = getattr(hashlib, hasher)()
396 | logger.debug('Digest specified: %s' % digest)
397 | # The following code is equivalent to urlretrieve.
398 | # We need to do it this way so that we can compute the
399 | # digest of the file as we go.
400 | with open(destfile, 'wb') as dfp:
401 | # addinfourl is not a context manager on 2.x
402 | # so we have to use try/finally
403 | sfp = self.send_request(Request(url))
404 | try:
405 | headers = sfp.info()
406 | blocksize = 8192
407 | size = -1
408 | read = 0
409 | blocknum = 0
410 | if "content-length" in headers:
411 | size = int(headers["Content-Length"])
412 | if reporthook:
413 | reporthook(blocknum, blocksize, size)
414 | while True:
415 | block = sfp.read(blocksize)
416 | if not block:
417 | break
418 | read += len(block)
419 | dfp.write(block)
420 | if digester:
421 | digester.update(block)
422 | blocknum += 1
423 | if reporthook:
424 | reporthook(blocknum, blocksize, size)
425 | finally:
426 | sfp.close()
427 |
428 | # check that we got the whole file, if we can
429 | if size >= 0 and read < size:
430 | raise DistlibException(
431 | 'retrieval incomplete: got only %d out of %d bytes'
432 | % (read, size))
433 | # if we have a digest, it must match.
434 | if digester:
435 | actual = digester.hexdigest()
436 | if digest != actual:
437 | raise DistlibException('%s digest mismatch for %s: expected '
438 | '%s, got %s' % (hasher, destfile,
439 | digest, actual))
440 | logger.debug('Digest verified: %s', digest)
441 |
442 | def send_request(self, req):
443 | """
444 | Send a standard library :class:`Request` to PyPI and return its
445 | response.
446 |
447 | :param req: The request to send.
448 | :return: The HTTP response from PyPI (a standard library HTTPResponse).
449 | """
450 | handlers = []
451 | if self.password_handler:
452 | handlers.append(self.password_handler)
453 | if self.ssl_verifier:
454 | handlers.append(self.ssl_verifier)
455 | opener = build_opener(*handlers)
456 | return opener.open(req)
457 |
458 | def encode_request(self, fields, files):
459 | """
460 | Encode fields and files for posting to an HTTP server.
461 |
462 | :param fields: The fields to send as a list of (fieldname, value)
463 | tuples.
464 | :param files: The files to send as a list of (fieldname, filename,
465 | file_bytes) tuple.
466 | """
467 | # Adapted from packaging, which in turn was adapted from
468 | # http://code.activestate.com/recipes/146306
469 |
470 | parts = []
471 | boundary = self.boundary
472 | for k, values in fields:
473 | if not isinstance(values, (list, tuple)):
474 | values = [values]
475 |
476 | for v in values:
477 | parts.extend((
478 | b'--' + boundary,
479 | ('Content-Disposition: form-data; name="%s"' %
480 | k).encode('utf-8'),
481 | b'',
482 | v.encode('utf-8')))
483 | for key, filename, value in files:
484 | parts.extend((
485 | b'--' + boundary,
486 | ('Content-Disposition: form-data; name="%s"; filename="%s"' %
487 | (key, filename)).encode('utf-8'),
488 | b'',
489 | value))
490 |
491 | parts.extend((b'--' + boundary + b'--', b''))
492 |
493 | body = b'\r\n'.join(parts)
494 | ct = b'multipart/form-data; boundary=' + boundary
495 | headers = {
496 | 'Content-type': ct,
497 | 'Content-length': str(len(body))
498 | }
499 | return Request(self.url, body, headers)
500 |
501 | def search(self, terms, operator=None): # pragma: no cover
502 | if isinstance(terms, string_types):
503 | terms = {'name': terms}
504 | rpc_proxy = ServerProxy(self.url, timeout=3.0)
505 | try:
506 | return rpc_proxy.search(terms, operator or 'and')
507 | finally:
508 | rpc_proxy('close')()
509 |
```