#
tokens: 47037/50000 1/808 files (page 143/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 143 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/distro/distro.py:
--------------------------------------------------------------------------------

```python
   1 | #!/usr/bin/env python
   2 | # Copyright 2015-2021 Nir Cohen
   3 | #
   4 | # Licensed under the Apache License, Version 2.0 (the "License");
   5 | # you may not use this file except in compliance with the License.
   6 | # You may obtain a copy of the License at
   7 | #
   8 | # http://www.apache.org/licenses/LICENSE-2.0
   9 | #
  10 | # Unless required by applicable law or agreed to in writing, software
  11 | # distributed under the License is distributed on an "AS IS" BASIS,
  12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 | # See the License for the specific language governing permissions and
  14 | # limitations under the License.
  15 | 
  16 | """
  17 | The ``distro`` package (``distro`` stands for Linux Distribution) provides
  18 | information about the Linux distribution it runs on, such as a reliable
  19 | machine-readable distro ID, or version information.
  20 | 
  21 | It is the recommended replacement for Python's original
  22 | :py:func:`platform.linux_distribution` function, but it provides much more
  23 | functionality. An alternative implementation became necessary because Python
  24 | 3.5 deprecated this function, and Python 3.8 removed it altogether. Its
  25 | predecessor function :py:func:`platform.dist` was already deprecated since
  26 | Python 2.6 and removed in Python 3.8. Still, there are many cases in which
  27 | access to OS distribution information is needed. See `Python issue 1322
  28 | <https://bugs.python.org/issue1322>`_ for more information.
  29 | """
  30 | 
  31 | import argparse
  32 | import json
  33 | import logging
  34 | import os
  35 | import re
  36 | import shlex
  37 | import subprocess
  38 | import sys
  39 | import warnings
  40 | from typing import (
  41 |     Any,
  42 |     Callable,
  43 |     Dict,
  44 |     Iterable,
  45 |     Optional,
  46 |     Sequence,
  47 |     TextIO,
  48 |     Tuple,
  49 |     Type,
  50 | )
  51 | 
  52 | try:
  53 |     from typing import TypedDict
  54 | except ImportError:
  55 |     # Python 3.7
  56 |     TypedDict = dict
  57 | 
  58 | __version__ = "1.9.0"
  59 | 
  60 | 
  61 | class VersionDict(TypedDict):
  62 |     major: str
  63 |     minor: str
  64 |     build_number: str
  65 | 
  66 | 
  67 | class InfoDict(TypedDict):
  68 |     id: str
  69 |     version: str
  70 |     version_parts: VersionDict
  71 |     like: str
  72 |     codename: str
  73 | 
  74 | 
  75 | _UNIXCONFDIR = os.environ.get("UNIXCONFDIR", "/etc")
  76 | _UNIXUSRLIBDIR = os.environ.get("UNIXUSRLIBDIR", "/usr/lib")
  77 | _OS_RELEASE_BASENAME = "os-release"
  78 | 
  79 | #: Translation table for normalizing the "ID" attribute defined in os-release
  80 | #: files, for use by the :func:`distro.id` method.
  81 | #:
  82 | #: * Key: Value as defined in the os-release file, translated to lower case,
  83 | #:   with blanks translated to underscores.
  84 | #:
  85 | #: * Value: Normalized value.
  86 | NORMALIZED_OS_ID = {
  87 |     "ol": "oracle",  # Oracle Linux
  88 |     "opensuse-leap": "opensuse",  # Newer versions of OpenSuSE report as opensuse-leap
  89 | }
  90 | 
  91 | #: Translation table for normalizing the "Distributor ID" attribute returned by
  92 | #: the lsb_release command, for use by the :func:`distro.id` method.
  93 | #:
  94 | #: * Key: Value as returned by the lsb_release command, translated to lower
  95 | #:   case, with blanks translated to underscores.
  96 | #:
  97 | #: * Value: Normalized value.
  98 | NORMALIZED_LSB_ID = {
  99 |     "enterpriseenterpriseas": "oracle",  # Oracle Enterprise Linux 4
 100 |     "enterpriseenterpriseserver": "oracle",  # Oracle Linux 5
 101 |     "redhatenterpriseworkstation": "rhel",  # RHEL 6, 7 Workstation
 102 |     "redhatenterpriseserver": "rhel",  # RHEL 6, 7 Server
 103 |     "redhatenterprisecomputenode": "rhel",  # RHEL 6 ComputeNode
 104 | }
 105 | 
 106 | #: Translation table for normalizing the distro ID derived from the file name
 107 | #: of distro release files, for use by the :func:`distro.id` method.
 108 | #:
 109 | #: * Key: Value as derived from the file name of a distro release file,
 110 | #:   translated to lower case, with blanks translated to underscores.
 111 | #:
 112 | #: * Value: Normalized value.
 113 | NORMALIZED_DISTRO_ID = {
 114 |     "redhat": "rhel",  # RHEL 6.x, 7.x
 115 | }
 116 | 
 117 | # Pattern for content of distro release file (reversed)
 118 | _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile(
 119 |     r"(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)"
 120 | )
 121 | 
 122 | # Pattern for base file name of distro release file
 123 | _DISTRO_RELEASE_BASENAME_PATTERN = re.compile(r"(\w+)[-_](release|version)$")
 124 | 
 125 | # Base file names to be looked up for if _UNIXCONFDIR is not readable.
 126 | _DISTRO_RELEASE_BASENAMES = [
 127 |     "SuSE-release",
 128 |     "altlinux-release",
 129 |     "arch-release",
 130 |     "base-release",
 131 |     "centos-release",
 132 |     "fedora-release",
 133 |     "gentoo-release",
 134 |     "mageia-release",
 135 |     "mandrake-release",
 136 |     "mandriva-release",
 137 |     "mandrivalinux-release",
 138 |     "manjaro-release",
 139 |     "oracle-release",
 140 |     "redhat-release",
 141 |     "rocky-release",
 142 |     "sl-release",
 143 |     "slackware-version",
 144 | ]
 145 | 
 146 | # Base file names to be ignored when searching for distro release file
 147 | _DISTRO_RELEASE_IGNORE_BASENAMES = (
 148 |     "debian_version",
 149 |     "lsb-release",
 150 |     "oem-release",
 151 |     _OS_RELEASE_BASENAME,
 152 |     "system-release",
 153 |     "plesk-release",
 154 |     "iredmail-release",
 155 |     "board-release",
 156 |     "ec2_version",
 157 | )
 158 | 
 159 | 
 160 | def linux_distribution(full_distribution_name: bool = True) -> Tuple[str, str, str]:
 161 |     """
 162 |     .. deprecated:: 1.6.0
 163 | 
 164 |         :func:`distro.linux_distribution()` is deprecated. It should only be
 165 |         used as a compatibility shim with Python's
 166 |         :py:func:`platform.linux_distribution()`. Please use :func:`distro.id`,
 167 |         :func:`distro.version` and :func:`distro.name` instead.
 168 | 
 169 |     Return information about the current OS distribution as a tuple
 170 |     ``(id_name, version, codename)`` with items as follows:
 171 | 
 172 |     * ``id_name``:  If *full_distribution_name* is false, the result of
 173 |       :func:`distro.id`. Otherwise, the result of :func:`distro.name`.
 174 | 
 175 |     * ``version``:  The result of :func:`distro.version`.
 176 | 
 177 |     * ``codename``:  The extra item (usually in parentheses) after the
 178 |       os-release version number, or the result of :func:`distro.codename`.
 179 | 
 180 |     The interface of this function is compatible with the original
 181 |     :py:func:`platform.linux_distribution` function, supporting a subset of
 182 |     its parameters.
 183 | 
 184 |     The data it returns may not exactly be the same, because it uses more data
 185 |     sources than the original function, and that may lead to different data if
 186 |     the OS distribution is not consistent across multiple data sources it
 187 |     provides (there are indeed such distributions ...).
 188 | 
 189 |     Another reason for differences is the fact that the :func:`distro.id`
 190 |     method normalizes the distro ID string to a reliable machine-readable value
 191 |     for a number of popular OS distributions.
 192 |     """
 193 |     warnings.warn(
 194 |         "distro.linux_distribution() is deprecated. It should only be used as a "
 195 |         "compatibility shim with Python's platform.linux_distribution(). Please use "
 196 |         "distro.id(), distro.version() and distro.name() instead.",
 197 |         DeprecationWarning,
 198 |         stacklevel=2,
 199 |     )
 200 |     return _distro.linux_distribution(full_distribution_name)
 201 | 
 202 | 
 203 | def id() -> str:
 204 |     """
 205 |     Return the distro ID of the current distribution, as a
 206 |     machine-readable string.
 207 | 
 208 |     For a number of OS distributions, the returned distro ID value is
 209 |     *reliable*, in the sense that it is documented and that it does not change
 210 |     across releases of the distribution.
 211 | 
 212 |     This package maintains the following reliable distro ID values:
 213 | 
 214 |     ==============  =========================================
 215 |     Distro ID       Distribution
 216 |     ==============  =========================================
 217 |     "ubuntu"        Ubuntu
 218 |     "debian"        Debian
 219 |     "rhel"          RedHat Enterprise Linux
 220 |     "centos"        CentOS
 221 |     "fedora"        Fedora
 222 |     "sles"          SUSE Linux Enterprise Server
 223 |     "opensuse"      openSUSE
 224 |     "amzn"          Amazon Linux
 225 |     "arch"          Arch Linux
 226 |     "buildroot"     Buildroot
 227 |     "cloudlinux"    CloudLinux OS
 228 |     "exherbo"       Exherbo Linux
 229 |     "gentoo"        GenToo Linux
 230 |     "ibm_powerkvm"  IBM PowerKVM
 231 |     "kvmibm"        KVM for IBM z Systems
 232 |     "linuxmint"     Linux Mint
 233 |     "mageia"        Mageia
 234 |     "mandriva"      Mandriva Linux
 235 |     "parallels"     Parallels
 236 |     "pidora"        Pidora
 237 |     "raspbian"      Raspbian
 238 |     "oracle"        Oracle Linux (and Oracle Enterprise Linux)
 239 |     "scientific"    Scientific Linux
 240 |     "slackware"     Slackware
 241 |     "xenserver"     XenServer
 242 |     "openbsd"       OpenBSD
 243 |     "netbsd"        NetBSD
 244 |     "freebsd"       FreeBSD
 245 |     "midnightbsd"   MidnightBSD
 246 |     "rocky"         Rocky Linux
 247 |     "aix"           AIX
 248 |     "guix"          Guix System
 249 |     "altlinux"      ALT Linux
 250 |     ==============  =========================================
 251 | 
 252 |     If you have a need to get distros for reliable IDs added into this set,
 253 |     or if you find that the :func:`distro.id` function returns a different
 254 |     distro ID for one of the listed distros, please create an issue in the
 255 |     `distro issue tracker`_.
 256 | 
 257 |     **Lookup hierarchy and transformations:**
 258 | 
 259 |     First, the ID is obtained from the following sources, in the specified
 260 |     order. The first available and non-empty value is used:
 261 | 
 262 |     * the value of the "ID" attribute of the os-release file,
 263 | 
 264 |     * the value of the "Distributor ID" attribute returned by the lsb_release
 265 |       command,
 266 | 
 267 |     * the first part of the file name of the distro release file,
 268 | 
 269 |     The so determined ID value then passes the following transformations,
 270 |     before it is returned by this method:
 271 | 
 272 |     * it is translated to lower case,
 273 | 
 274 |     * blanks (which should not be there anyway) are translated to underscores,
 275 | 
 276 |     * a normalization of the ID is performed, based upon
 277 |       `normalization tables`_. The purpose of this normalization is to ensure
 278 |       that the ID is as reliable as possible, even across incompatible changes
 279 |       in the OS distributions. A common reason for an incompatible change is
 280 |       the addition of an os-release file, or the addition of the lsb_release
 281 |       command, with ID values that differ from what was previously determined
 282 |       from the distro release file name.
 283 |     """
 284 |     return _distro.id()
 285 | 
 286 | 
 287 | def name(pretty: bool = False) -> str:
 288 |     """
 289 |     Return the name of the current OS distribution, as a human-readable
 290 |     string.
 291 | 
 292 |     If *pretty* is false, the name is returned without version or codename.
 293 |     (e.g. "CentOS Linux")
 294 | 
 295 |     If *pretty* is true, the version and codename are appended.
 296 |     (e.g. "CentOS Linux 7.1.1503 (Core)")
 297 | 
 298 |     **Lookup hierarchy:**
 299 | 
 300 |     The name is obtained from the following sources, in the specified order.
 301 |     The first available and non-empty value is used:
 302 | 
 303 |     * If *pretty* is false:
 304 | 
 305 |       - the value of the "NAME" attribute of the os-release file,
 306 | 
 307 |       - the value of the "Distributor ID" attribute returned by the lsb_release
 308 |         command,
 309 | 
 310 |       - the value of the "<name>" field of the distro release file.
 311 | 
 312 |     * If *pretty* is true:
 313 | 
 314 |       - the value of the "PRETTY_NAME" attribute of the os-release file,
 315 | 
 316 |       - the value of the "Description" attribute returned by the lsb_release
 317 |         command,
 318 | 
 319 |       - the value of the "<name>" field of the distro release file, appended
 320 |         with the value of the pretty version ("<version_id>" and "<codename>"
 321 |         fields) of the distro release file, if available.
 322 |     """
 323 |     return _distro.name(pretty)
 324 | 
 325 | 
 326 | def version(pretty: bool = False, best: bool = False) -> str:
 327 |     """
 328 |     Return the version of the current OS distribution, as a human-readable
 329 |     string.
 330 | 
 331 |     If *pretty* is false, the version is returned without codename (e.g.
 332 |     "7.0").
 333 | 
 334 |     If *pretty* is true, the codename in parenthesis is appended, if the
 335 |     codename is non-empty (e.g. "7.0 (Maipo)").
 336 | 
 337 |     Some distributions provide version numbers with different precisions in
 338 |     the different sources of distribution information. Examining the different
 339 |     sources in a fixed priority order does not always yield the most precise
 340 |     version (e.g. for Debian 8.2, or CentOS 7.1).
 341 | 
 342 |     Some other distributions may not provide this kind of information. In these
 343 |     cases, an empty string would be returned. This behavior can be observed
 344 |     with rolling releases distributions (e.g. Arch Linux).
 345 | 
 346 |     The *best* parameter can be used to control the approach for the returned
 347 |     version:
 348 | 
 349 |     If *best* is false, the first non-empty version number in priority order of
 350 |     the examined sources is returned.
 351 | 
 352 |     If *best* is true, the most precise version number out of all examined
 353 |     sources is returned.
 354 | 
 355 |     **Lookup hierarchy:**
 356 | 
 357 |     In all cases, the version number is obtained from the following sources.
 358 |     If *best* is false, this order represents the priority order:
 359 | 
 360 |     * the value of the "VERSION_ID" attribute of the os-release file,
 361 |     * the value of the "Release" attribute returned by the lsb_release
 362 |       command,
 363 |     * the version number parsed from the "<version_id>" field of the first line
 364 |       of the distro release file,
 365 |     * the version number parsed from the "PRETTY_NAME" attribute of the
 366 |       os-release file, if it follows the format of the distro release files.
 367 |     * the version number parsed from the "Description" attribute returned by
 368 |       the lsb_release command, if it follows the format of the distro release
 369 |       files.
 370 |     """
 371 |     return _distro.version(pretty, best)
 372 | 
 373 | 
 374 | def version_parts(best: bool = False) -> Tuple[str, str, str]:
 375 |     """
 376 |     Return the version of the current OS distribution as a tuple
 377 |     ``(major, minor, build_number)`` with items as follows:
 378 | 
 379 |     * ``major``:  The result of :func:`distro.major_version`.
 380 | 
 381 |     * ``minor``:  The result of :func:`distro.minor_version`.
 382 | 
 383 |     * ``build_number``:  The result of :func:`distro.build_number`.
 384 | 
 385 |     For a description of the *best* parameter, see the :func:`distro.version`
 386 |     method.
 387 |     """
 388 |     return _distro.version_parts(best)
 389 | 
 390 | 
 391 | def major_version(best: bool = False) -> str:
 392 |     """
 393 |     Return the major version of the current OS distribution, as a string,
 394 |     if provided.
 395 |     Otherwise, the empty string is returned. The major version is the first
 396 |     part of the dot-separated version string.
 397 | 
 398 |     For a description of the *best* parameter, see the :func:`distro.version`
 399 |     method.
 400 |     """
 401 |     return _distro.major_version(best)
 402 | 
 403 | 
 404 | def minor_version(best: bool = False) -> str:
 405 |     """
 406 |     Return the minor version of the current OS distribution, as a string,
 407 |     if provided.
 408 |     Otherwise, the empty string is returned. The minor version is the second
 409 |     part of the dot-separated version string.
 410 | 
 411 |     For a description of the *best* parameter, see the :func:`distro.version`
 412 |     method.
 413 |     """
 414 |     return _distro.minor_version(best)
 415 | 
 416 | 
 417 | def build_number(best: bool = False) -> str:
 418 |     """
 419 |     Return the build number of the current OS distribution, as a string,
 420 |     if provided.
 421 |     Otherwise, the empty string is returned. The build number is the third part
 422 |     of the dot-separated version string.
 423 | 
 424 |     For a description of the *best* parameter, see the :func:`distro.version`
 425 |     method.
 426 |     """
 427 |     return _distro.build_number(best)
 428 | 
 429 | 
 430 | def like() -> str:
 431 |     """
 432 |     Return a space-separated list of distro IDs of distributions that are
 433 |     closely related to the current OS distribution in regards to packaging
 434 |     and programming interfaces, for example distributions the current
 435 |     distribution is a derivative from.
 436 | 
 437 |     **Lookup hierarchy:**
 438 | 
 439 |     This information item is only provided by the os-release file.
 440 |     For details, see the description of the "ID_LIKE" attribute in the
 441 |     `os-release man page
 442 |     <http://www.freedesktop.org/software/systemd/man/os-release.html>`_.
 443 |     """
 444 |     return _distro.like()
 445 | 
 446 | 
 447 | def codename() -> str:
 448 |     """
 449 |     Return the codename for the release of the current OS distribution,
 450 |     as a string.
 451 | 
 452 |     If the distribution does not have a codename, an empty string is returned.
 453 | 
 454 |     Note that the returned codename is not always really a codename. For
 455 |     example, openSUSE returns "x86_64". This function does not handle such
 456 |     cases in any special way and just returns the string it finds, if any.
 457 | 
 458 |     **Lookup hierarchy:**
 459 | 
 460 |     * the codename within the "VERSION" attribute of the os-release file, if
 461 |       provided,
 462 | 
 463 |     * the value of the "Codename" attribute returned by the lsb_release
 464 |       command,
 465 | 
 466 |     * the value of the "<codename>" field of the distro release file.
 467 |     """
 468 |     return _distro.codename()
 469 | 
 470 | 
 471 | def info(pretty: bool = False, best: bool = False) -> InfoDict:
 472 |     """
 473 |     Return certain machine-readable information items about the current OS
 474 |     distribution in a dictionary, as shown in the following example:
 475 | 
 476 |     .. sourcecode:: python
 477 | 
 478 |         {
 479 |             'id': 'rhel',
 480 |             'version': '7.0',
 481 |             'version_parts': {
 482 |                 'major': '7',
 483 |                 'minor': '0',
 484 |                 'build_number': ''
 485 |             },
 486 |             'like': 'fedora',
 487 |             'codename': 'Maipo'
 488 |         }
 489 | 
 490 |     The dictionary structure and keys are always the same, regardless of which
 491 |     information items are available in the underlying data sources. The values
 492 |     for the various keys are as follows:
 493 | 
 494 |     * ``id``:  The result of :func:`distro.id`.
 495 | 
 496 |     * ``version``:  The result of :func:`distro.version`.
 497 | 
 498 |     * ``version_parts -> major``:  The result of :func:`distro.major_version`.
 499 | 
 500 |     * ``version_parts -> minor``:  The result of :func:`distro.minor_version`.
 501 | 
 502 |     * ``version_parts -> build_number``:  The result of
 503 |       :func:`distro.build_number`.
 504 | 
 505 |     * ``like``:  The result of :func:`distro.like`.
 506 | 
 507 |     * ``codename``:  The result of :func:`distro.codename`.
 508 | 
 509 |     For a description of the *pretty* and *best* parameters, see the
 510 |     :func:`distro.version` method.
 511 |     """
 512 |     return _distro.info(pretty, best)
 513 | 
 514 | 
 515 | def os_release_info() -> Dict[str, str]:
 516 |     """
 517 |     Return a dictionary containing key-value pairs for the information items
 518 |     from the os-release file data source of the current OS distribution.
 519 | 
 520 |     See `os-release file`_ for details about these information items.
 521 |     """
 522 |     return _distro.os_release_info()
 523 | 
 524 | 
 525 | def lsb_release_info() -> Dict[str, str]:
 526 |     """
 527 |     Return a dictionary containing key-value pairs for the information items
 528 |     from the lsb_release command data source of the current OS distribution.
 529 | 
 530 |     See `lsb_release command output`_ for details about these information
 531 |     items.
 532 |     """
 533 |     return _distro.lsb_release_info()
 534 | 
 535 | 
 536 | def distro_release_info() -> Dict[str, str]:
 537 |     """
 538 |     Return a dictionary containing key-value pairs for the information items
 539 |     from the distro release file data source of the current OS distribution.
 540 | 
 541 |     See `distro release file`_ for details about these information items.
 542 |     """
 543 |     return _distro.distro_release_info()
 544 | 
 545 | 
 546 | def uname_info() -> Dict[str, str]:
 547 |     """
 548 |     Return a dictionary containing key-value pairs for the information items
 549 |     from the distro release file data source of the current OS distribution.
 550 |     """
 551 |     return _distro.uname_info()
 552 | 
 553 | 
 554 | def os_release_attr(attribute: str) -> str:
 555 |     """
 556 |     Return a single named information item from the os-release file data source
 557 |     of the current OS distribution.
 558 | 
 559 |     Parameters:
 560 | 
 561 |     * ``attribute`` (string): Key of the information item.
 562 | 
 563 |     Returns:
 564 | 
 565 |     * (string): Value of the information item, if the item exists.
 566 |       The empty string, if the item does not exist.
 567 | 
 568 |     See `os-release file`_ for details about these information items.
 569 |     """
 570 |     return _distro.os_release_attr(attribute)
 571 | 
 572 | 
 573 | def lsb_release_attr(attribute: str) -> str:
 574 |     """
 575 |     Return a single named information item from the lsb_release command output
 576 |     data source of the current OS distribution.
 577 | 
 578 |     Parameters:
 579 | 
 580 |     * ``attribute`` (string): Key of the information item.
 581 | 
 582 |     Returns:
 583 | 
 584 |     * (string): Value of the information item, if the item exists.
 585 |       The empty string, if the item does not exist.
 586 | 
 587 |     See `lsb_release command output`_ for details about these information
 588 |     items.
 589 |     """
 590 |     return _distro.lsb_release_attr(attribute)
 591 | 
 592 | 
 593 | def distro_release_attr(attribute: str) -> str:
 594 |     """
 595 |     Return a single named information item from the distro release file
 596 |     data source of the current OS distribution.
 597 | 
 598 |     Parameters:
 599 | 
 600 |     * ``attribute`` (string): Key of the information item.
 601 | 
 602 |     Returns:
 603 | 
 604 |     * (string): Value of the information item, if the item exists.
 605 |       The empty string, if the item does not exist.
 606 | 
 607 |     See `distro release file`_ for details about these information items.
 608 |     """
 609 |     return _distro.distro_release_attr(attribute)
 610 | 
 611 | 
 612 | def uname_attr(attribute: str) -> str:
 613 |     """
 614 |     Return a single named information item from the distro release file
 615 |     data source of the current OS distribution.
 616 | 
 617 |     Parameters:
 618 | 
 619 |     * ``attribute`` (string): Key of the information item.
 620 | 
 621 |     Returns:
 622 | 
 623 |     * (string): Value of the information item, if the item exists.
 624 |                 The empty string, if the item does not exist.
 625 |     """
 626 |     return _distro.uname_attr(attribute)
 627 | 
 628 | 
 629 | try:
 630 |     from functools import cached_property
 631 | except ImportError:
 632 |     # Python < 3.8
 633 |     class cached_property:  # type: ignore
 634 |         """A version of @property which caches the value.  On access, it calls the
 635 |         underlying function and sets the value in `__dict__` so future accesses
 636 |         will not re-call the property.
 637 |         """
 638 | 
 639 |         def __init__(self, f: Callable[[Any], Any]) -> None:
 640 |             self._fname = f.__name__
 641 |             self._f = f
 642 | 
 643 |         def __get__(self, obj: Any, owner: Type[Any]) -> Any:
 644 |             assert obj is not None, f"call {self._fname} on an instance"
 645 |             ret = obj.__dict__[self._fname] = self._f(obj)
 646 |             return ret
 647 | 
 648 | 
 649 | class LinuxDistribution:
 650 |     """
 651 |     Provides information about a OS distribution.
 652 | 
 653 |     This package creates a private module-global instance of this class with
 654 |     default initialization arguments, that is used by the
 655 |     `consolidated accessor functions`_ and `single source accessor functions`_.
 656 |     By using default initialization arguments, that module-global instance
 657 |     returns data about the current OS distribution (i.e. the distro this
 658 |     package runs on).
 659 | 
 660 |     Normally, it is not necessary to create additional instances of this class.
 661 |     However, in situations where control is needed over the exact data sources
 662 |     that are used, instances of this class can be created with a specific
 663 |     distro release file, or a specific os-release file, or without invoking the
 664 |     lsb_release command.
 665 |     """
 666 | 
 667 |     def __init__(
 668 |         self,
 669 |         include_lsb: Optional[bool] = None,
 670 |         os_release_file: str = "",
 671 |         distro_release_file: str = "",
 672 |         include_uname: Optional[bool] = None,
 673 |         root_dir: Optional[str] = None,
 674 |         include_oslevel: Optional[bool] = None,
 675 |     ) -> None:
 676 |         """
 677 |         The initialization method of this class gathers information from the
 678 |         available data sources, and stores that in private instance attributes.
 679 |         Subsequent access to the information items uses these private instance
 680 |         attributes, so that the data sources are read only once.
 681 | 
 682 |         Parameters:
 683 | 
 684 |         * ``include_lsb`` (bool): Controls whether the
 685 |           `lsb_release command output`_ is included as a data source.
 686 | 
 687 |           If the lsb_release command is not available in the program execution
 688 |           path, the data source for the lsb_release command will be empty.
 689 | 
 690 |         * ``os_release_file`` (string): The path name of the
 691 |           `os-release file`_ that is to be used as a data source.
 692 | 
 693 |           An empty string (the default) will cause the default path name to
 694 |           be used (see `os-release file`_ for details).
 695 | 
 696 |           If the specified or defaulted os-release file does not exist, the
 697 |           data source for the os-release file will be empty.
 698 | 
 699 |         * ``distro_release_file`` (string): The path name of the
 700 |           `distro release file`_ that is to be used as a data source.
 701 | 
 702 |           An empty string (the default) will cause a default search algorithm
 703 |           to be used (see `distro release file`_ for details).
 704 | 
 705 |           If the specified distro release file does not exist, or if no default
 706 |           distro release file can be found, the data source for the distro
 707 |           release file will be empty.
 708 | 
 709 |         * ``include_uname`` (bool): Controls whether uname command output is
 710 |           included as a data source. If the uname command is not available in
 711 |           the program execution path the data source for the uname command will
 712 |           be empty.
 713 | 
 714 |         * ``root_dir`` (string): The absolute path to the root directory to use
 715 |           to find distro-related information files. Note that ``include_*``
 716 |           parameters must not be enabled in combination with ``root_dir``.
 717 | 
 718 |         * ``include_oslevel`` (bool): Controls whether (AIX) oslevel command
 719 |           output is included as a data source. If the oslevel command is not
 720 |           available in the program execution path the data source will be
 721 |           empty.
 722 | 
 723 |         Public instance attributes:
 724 | 
 725 |         * ``os_release_file`` (string): The path name of the
 726 |           `os-release file`_ that is actually used as a data source. The
 727 |           empty string if no distro release file is used as a data source.
 728 | 
 729 |         * ``distro_release_file`` (string): The path name of the
 730 |           `distro release file`_ that is actually used as a data source. The
 731 |           empty string if no distro release file is used as a data source.
 732 | 
 733 |         * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter.
 734 |           This controls whether the lsb information will be loaded.
 735 | 
 736 |         * ``include_uname`` (bool): The result of the ``include_uname``
 737 |           parameter. This controls whether the uname information will
 738 |           be loaded.
 739 | 
 740 |         * ``include_oslevel`` (bool): The result of the ``include_oslevel``
 741 |           parameter. This controls whether (AIX) oslevel information will be
 742 |           loaded.
 743 | 
 744 |         * ``root_dir`` (string): The result of the ``root_dir`` parameter.
 745 |           The absolute path to the root directory to use to find distro-related
 746 |           information files.
 747 | 
 748 |         Raises:
 749 | 
 750 |         * :py:exc:`ValueError`: Initialization parameters combination is not
 751 |            supported.
 752 | 
 753 |         * :py:exc:`OSError`: Some I/O issue with an os-release file or distro
 754 |           release file.
 755 | 
 756 |         * :py:exc:`UnicodeError`: A data source has unexpected characters or
 757 |           uses an unexpected encoding.
 758 |         """
 759 |         self.root_dir = root_dir
 760 |         self.etc_dir = os.path.join(root_dir, "etc") if root_dir else _UNIXCONFDIR
 761 |         self.usr_lib_dir = (
 762 |             os.path.join(root_dir, "usr/lib") if root_dir else _UNIXUSRLIBDIR
 763 |         )
 764 | 
 765 |         if os_release_file:
 766 |             self.os_release_file = os_release_file
 767 |         else:
 768 |             etc_dir_os_release_file = os.path.join(self.etc_dir, _OS_RELEASE_BASENAME)
 769 |             usr_lib_os_release_file = os.path.join(
 770 |                 self.usr_lib_dir, _OS_RELEASE_BASENAME
 771 |             )
 772 | 
 773 |             # NOTE: The idea is to respect order **and** have it set
 774 |             #       at all times for API backwards compatibility.
 775 |             if os.path.isfile(etc_dir_os_release_file) or not os.path.isfile(
 776 |                 usr_lib_os_release_file
 777 |             ):
 778 |                 self.os_release_file = etc_dir_os_release_file
 779 |             else:
 780 |                 self.os_release_file = usr_lib_os_release_file
 781 | 
 782 |         self.distro_release_file = distro_release_file or ""  # updated later
 783 | 
 784 |         is_root_dir_defined = root_dir is not None
 785 |         if is_root_dir_defined and (include_lsb or include_uname or include_oslevel):
 786 |             raise ValueError(
 787 |                 "Including subprocess data sources from specific root_dir is disallowed"
 788 |                 " to prevent false information"
 789 |             )
 790 |         self.include_lsb = (
 791 |             include_lsb if include_lsb is not None else not is_root_dir_defined
 792 |         )
 793 |         self.include_uname = (
 794 |             include_uname if include_uname is not None else not is_root_dir_defined
 795 |         )
 796 |         self.include_oslevel = (
 797 |             include_oslevel if include_oslevel is not None else not is_root_dir_defined
 798 |         )
 799 | 
 800 |     def __repr__(self) -> str:
 801 |         """Return repr of all info"""
 802 |         return (
 803 |             "LinuxDistribution("
 804 |             "os_release_file={self.os_release_file!r}, "
 805 |             "distro_release_file={self.distro_release_file!r}, "
 806 |             "include_lsb={self.include_lsb!r}, "
 807 |             "include_uname={self.include_uname!r}, "
 808 |             "include_oslevel={self.include_oslevel!r}, "
 809 |             "root_dir={self.root_dir!r}, "
 810 |             "_os_release_info={self._os_release_info!r}, "
 811 |             "_lsb_release_info={self._lsb_release_info!r}, "
 812 |             "_distro_release_info={self._distro_release_info!r}, "
 813 |             "_uname_info={self._uname_info!r}, "
 814 |             "_oslevel_info={self._oslevel_info!r})".format(self=self)
 815 |         )
 816 | 
 817 |     def linux_distribution(
 818 |         self, full_distribution_name: bool = True
 819 |     ) -> Tuple[str, str, str]:
 820 |         """
 821 |         Return information about the OS distribution that is compatible
 822 |         with Python's :func:`platform.linux_distribution`, supporting a subset
 823 |         of its parameters.
 824 | 
 825 |         For details, see :func:`distro.linux_distribution`.
 826 |         """
 827 |         return (
 828 |             self.name() if full_distribution_name else self.id(),
 829 |             self.version(),
 830 |             self._os_release_info.get("release_codename") or self.codename(),
 831 |         )
 832 | 
 833 |     def id(self) -> str:
 834 |         """Return the distro ID of the OS distribution, as a string.
 835 | 
 836 |         For details, see :func:`distro.id`.
 837 |         """
 838 | 
 839 |         def normalize(distro_id: str, table: Dict[str, str]) -> str:
 840 |             distro_id = distro_id.lower().replace(" ", "_")
 841 |             return table.get(distro_id, distro_id)
 842 | 
 843 |         distro_id = self.os_release_attr("id")
 844 |         if distro_id:
 845 |             return normalize(distro_id, NORMALIZED_OS_ID)
 846 | 
 847 |         distro_id = self.lsb_release_attr("distributor_id")
 848 |         if distro_id:
 849 |             return normalize(distro_id, NORMALIZED_LSB_ID)
 850 | 
 851 |         distro_id = self.distro_release_attr("id")
 852 |         if distro_id:
 853 |             return normalize(distro_id, NORMALIZED_DISTRO_ID)
 854 | 
 855 |         distro_id = self.uname_attr("id")
 856 |         if distro_id:
 857 |             return normalize(distro_id, NORMALIZED_DISTRO_ID)
 858 | 
 859 |         return ""
 860 | 
 861 |     def name(self, pretty: bool = False) -> str:
 862 |         """
 863 |         Return the name of the OS distribution, as a string.
 864 | 
 865 |         For details, see :func:`distro.name`.
 866 |         """
 867 |         name = (
 868 |             self.os_release_attr("name")
 869 |             or self.lsb_release_attr("distributor_id")
 870 |             or self.distro_release_attr("name")
 871 |             or self.uname_attr("name")
 872 |         )
 873 |         if pretty:
 874 |             name = self.os_release_attr("pretty_name") or self.lsb_release_attr(
 875 |                 "description"
 876 |             )
 877 |             if not name:
 878 |                 name = self.distro_release_attr("name") or self.uname_attr("name")
 879 |                 version = self.version(pretty=True)
 880 |                 if version:
 881 |                     name = f"{name} {version}"
 882 |         return name or ""
 883 | 
 884 |     def version(self, pretty: bool = False, best: bool = False) -> str:
 885 |         """
 886 |         Return the version of the OS distribution, as a string.
 887 | 
 888 |         For details, see :func:`distro.version`.
 889 |         """
 890 |         versions = [
 891 |             self.os_release_attr("version_id"),
 892 |             self.lsb_release_attr("release"),
 893 |             self.distro_release_attr("version_id"),
 894 |             self._parse_distro_release_content(self.os_release_attr("pretty_name")).get(
 895 |                 "version_id", ""
 896 |             ),
 897 |             self._parse_distro_release_content(
 898 |                 self.lsb_release_attr("description")
 899 |             ).get("version_id", ""),
 900 |             self.uname_attr("release"),
 901 |         ]
 902 |         if self.uname_attr("id").startswith("aix"):
 903 |             # On AIX platforms, prefer oslevel command output.
 904 |             versions.insert(0, self.oslevel_info())
 905 |         elif self.id() == "debian" or "debian" in self.like().split():
 906 |             # On Debian-like, add debian_version file content to candidates list.
 907 |             versions.append(self._debian_version)
 908 |         version = ""
 909 |         if best:
 910 |             # This algorithm uses the last version in priority order that has
 911 |             # the best precision. If the versions are not in conflict, that
 912 |             # does not matter; otherwise, using the last one instead of the
 913 |             # first one might be considered a surprise.
 914 |             for v in versions:
 915 |                 if v.count(".") > version.count(".") or version == "":
 916 |                     version = v
 917 |         else:
 918 |             for v in versions:
 919 |                 if v != "":
 920 |                     version = v
 921 |                     break
 922 |         if pretty and version and self.codename():
 923 |             version = f"{version} ({self.codename()})"
 924 |         return version
 925 | 
 926 |     def version_parts(self, best: bool = False) -> Tuple[str, str, str]:
 927 |         """
 928 |         Return the version of the OS distribution, as a tuple of version
 929 |         numbers.
 930 | 
 931 |         For details, see :func:`distro.version_parts`.
 932 |         """
 933 |         version_str = self.version(best=best)
 934 |         if version_str:
 935 |             version_regex = re.compile(r"(\d+)\.?(\d+)?\.?(\d+)?")
 936 |             matches = version_regex.match(version_str)
 937 |             if matches:
 938 |                 major, minor, build_number = matches.groups()
 939 |                 return major, minor or "", build_number or ""
 940 |         return "", "", ""
 941 | 
 942 |     def major_version(self, best: bool = False) -> str:
 943 |         """
 944 |         Return the major version number of the current distribution.
 945 | 
 946 |         For details, see :func:`distro.major_version`.
 947 |         """
 948 |         return self.version_parts(best)[0]
 949 | 
 950 |     def minor_version(self, best: bool = False) -> str:
 951 |         """
 952 |         Return the minor version number of the current distribution.
 953 | 
 954 |         For details, see :func:`distro.minor_version`.
 955 |         """
 956 |         return self.version_parts(best)[1]
 957 | 
 958 |     def build_number(self, best: bool = False) -> str:
 959 |         """
 960 |         Return the build number of the current distribution.
 961 | 
 962 |         For details, see :func:`distro.build_number`.
 963 |         """
 964 |         return self.version_parts(best)[2]
 965 | 
 966 |     def like(self) -> str:
 967 |         """
 968 |         Return the IDs of distributions that are like the OS distribution.
 969 | 
 970 |         For details, see :func:`distro.like`.
 971 |         """
 972 |         return self.os_release_attr("id_like") or ""
 973 | 
 974 |     def codename(self) -> str:
 975 |         """
 976 |         Return the codename of the OS distribution.
 977 | 
 978 |         For details, see :func:`distro.codename`.
 979 |         """
 980 |         try:
 981 |             # Handle os_release specially since distros might purposefully set
 982 |             # this to empty string to have no codename
 983 |             return self._os_release_info["codename"]
 984 |         except KeyError:
 985 |             return (
 986 |                 self.lsb_release_attr("codename")
 987 |                 or self.distro_release_attr("codename")
 988 |                 or ""
 989 |             )
 990 | 
 991 |     def info(self, pretty: bool = False, best: bool = False) -> InfoDict:
 992 |         """
 993 |         Return certain machine-readable information about the OS
 994 |         distribution.
 995 | 
 996 |         For details, see :func:`distro.info`.
 997 |         """
 998 |         return InfoDict(
 999 |             id=self.id(),
1000 |             version=self.version(pretty, best),
1001 |             version_parts=VersionDict(
1002 |                 major=self.major_version(best),
1003 |                 minor=self.minor_version(best),
1004 |                 build_number=self.build_number(best),
1005 |             ),
1006 |             like=self.like(),
1007 |             codename=self.codename(),
1008 |         )
1009 | 
1010 |     def os_release_info(self) -> Dict[str, str]:
1011 |         """
1012 |         Return a dictionary containing key-value pairs for the information
1013 |         items from the os-release file data source of the OS distribution.
1014 | 
1015 |         For details, see :func:`distro.os_release_info`.
1016 |         """
1017 |         return self._os_release_info
1018 | 
1019 |     def lsb_release_info(self) -> Dict[str, str]:
1020 |         """
1021 |         Return a dictionary containing key-value pairs for the information
1022 |         items from the lsb_release command data source of the OS
1023 |         distribution.
1024 | 
1025 |         For details, see :func:`distro.lsb_release_info`.
1026 |         """
1027 |         return self._lsb_release_info
1028 | 
1029 |     def distro_release_info(self) -> Dict[str, str]:
1030 |         """
1031 |         Return a dictionary containing key-value pairs for the information
1032 |         items from the distro release file data source of the OS
1033 |         distribution.
1034 | 
1035 |         For details, see :func:`distro.distro_release_info`.
1036 |         """
1037 |         return self._distro_release_info
1038 | 
1039 |     def uname_info(self) -> Dict[str, str]:
1040 |         """
1041 |         Return a dictionary containing key-value pairs for the information
1042 |         items from the uname command data source of the OS distribution.
1043 | 
1044 |         For details, see :func:`distro.uname_info`.
1045 |         """
1046 |         return self._uname_info
1047 | 
1048 |     def oslevel_info(self) -> str:
1049 |         """
1050 |         Return AIX' oslevel command output.
1051 |         """
1052 |         return self._oslevel_info
1053 | 
1054 |     def os_release_attr(self, attribute: str) -> str:
1055 |         """
1056 |         Return a single named information item from the os-release file data
1057 |         source of the OS distribution.
1058 | 
1059 |         For details, see :func:`distro.os_release_attr`.
1060 |         """
1061 |         return self._os_release_info.get(attribute, "")
1062 | 
1063 |     def lsb_release_attr(self, attribute: str) -> str:
1064 |         """
1065 |         Return a single named information item from the lsb_release command
1066 |         output data source of the OS distribution.
1067 | 
1068 |         For details, see :func:`distro.lsb_release_attr`.
1069 |         """
1070 |         return self._lsb_release_info.get(attribute, "")
1071 | 
1072 |     def distro_release_attr(self, attribute: str) -> str:
1073 |         """
1074 |         Return a single named information item from the distro release file
1075 |         data source of the OS distribution.
1076 | 
1077 |         For details, see :func:`distro.distro_release_attr`.
1078 |         """
1079 |         return self._distro_release_info.get(attribute, "")
1080 | 
1081 |     def uname_attr(self, attribute: str) -> str:
1082 |         """
1083 |         Return a single named information item from the uname command
1084 |         output data source of the OS distribution.
1085 | 
1086 |         For details, see :func:`distro.uname_attr`.
1087 |         """
1088 |         return self._uname_info.get(attribute, "")
1089 | 
1090 |     @cached_property
1091 |     def _os_release_info(self) -> Dict[str, str]:
1092 |         """
1093 |         Get the information items from the specified os-release file.
1094 | 
1095 |         Returns:
1096 |             A dictionary containing all information items.
1097 |         """
1098 |         if os.path.isfile(self.os_release_file):
1099 |             with open(self.os_release_file, encoding="utf-8") as release_file:
1100 |                 return self._parse_os_release_content(release_file)
1101 |         return {}
1102 | 
1103 |     @staticmethod
1104 |     def _parse_os_release_content(lines: TextIO) -> Dict[str, str]:
1105 |         """
1106 |         Parse the lines of an os-release file.
1107 | 
1108 |         Parameters:
1109 | 
1110 |         * lines: Iterable through the lines in the os-release file.
1111 |                  Each line must be a unicode string or a UTF-8 encoded byte
1112 |                  string.
1113 | 
1114 |         Returns:
1115 |             A dictionary containing all information items.
1116 |         """
1117 |         props = {}
1118 |         lexer = shlex.shlex(lines, posix=True)
1119 |         lexer.whitespace_split = True
1120 | 
1121 |         tokens = list(lexer)
1122 |         for token in tokens:
1123 |             # At this point, all shell-like parsing has been done (i.e.
1124 |             # comments processed, quotes and backslash escape sequences
1125 |             # processed, multi-line values assembled, trailing newlines
1126 |             # stripped, etc.), so the tokens are now either:
1127 |             # * variable assignments: var=value
1128 |             # * commands or their arguments (not allowed in os-release)
1129 |             # Ignore any tokens that are not variable assignments
1130 |             if "=" in token:
1131 |                 k, v = token.split("=", 1)
1132 |                 props[k.lower()] = v
1133 | 
1134 |         if "version" in props:
1135 |             # extract release codename (if any) from version attribute
1136 |             match = re.search(r"\((\D+)\)|,\s*(\D+)", props["version"])
1137 |             if match:
1138 |                 release_codename = match.group(1) or match.group(2)
1139 |                 props["codename"] = props["release_codename"] = release_codename
1140 | 
1141 |         if "version_codename" in props:
1142 |             # os-release added a version_codename field.  Use that in
1143 |             # preference to anything else Note that some distros purposefully
1144 |             # do not have code names.  They should be setting
1145 |             # version_codename=""
1146 |             props["codename"] = props["version_codename"]
1147 |         elif "ubuntu_codename" in props:
1148 |             # Same as above but a non-standard field name used on older Ubuntus
1149 |             props["codename"] = props["ubuntu_codename"]
1150 | 
1151 |         return props
1152 | 
1153 |     @cached_property
1154 |     def _lsb_release_info(self) -> Dict[str, str]:
1155 |         """
1156 |         Get the information items from the lsb_release command output.
1157 | 
1158 |         Returns:
1159 |             A dictionary containing all information items.
1160 |         """
1161 |         if not self.include_lsb:
1162 |             return {}
1163 |         try:
1164 |             cmd = ("lsb_release", "-a")
1165 |             stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
1166 |         # Command not found or lsb_release returned error
1167 |         except (OSError, subprocess.CalledProcessError):
1168 |             return {}
1169 |         content = self._to_str(stdout).splitlines()
1170 |         return self._parse_lsb_release_content(content)
1171 | 
1172 |     @staticmethod
1173 |     def _parse_lsb_release_content(lines: Iterable[str]) -> Dict[str, str]:
1174 |         """
1175 |         Parse the output of the lsb_release command.
1176 | 
1177 |         Parameters:
1178 | 
1179 |         * lines: Iterable through the lines of the lsb_release output.
1180 |                  Each line must be a unicode string or a UTF-8 encoded byte
1181 |                  string.
1182 | 
1183 |         Returns:
1184 |             A dictionary containing all information items.
1185 |         """
1186 |         props = {}
1187 |         for line in lines:
1188 |             kv = line.strip("\n").split(":", 1)
1189 |             if len(kv) != 2:
1190 |                 # Ignore lines without colon.
1191 |                 continue
1192 |             k, v = kv
1193 |             props.update({k.replace(" ", "_").lower(): v.strip()})
1194 |         return props
1195 | 
1196 |     @cached_property
1197 |     def _uname_info(self) -> Dict[str, str]:
1198 |         if not self.include_uname:
1199 |             return {}
1200 |         try:
1201 |             cmd = ("uname", "-rs")
1202 |             stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
1203 |         except OSError:
1204 |             return {}
1205 |         content = self._to_str(stdout).splitlines()
1206 |         return self._parse_uname_content(content)
1207 | 
1208 |     @cached_property
1209 |     def _oslevel_info(self) -> str:
1210 |         if not self.include_oslevel:
1211 |             return ""
1212 |         try:
1213 |             stdout = subprocess.check_output("oslevel", stderr=subprocess.DEVNULL)
1214 |         except (OSError, subprocess.CalledProcessError):
1215 |             return ""
1216 |         return self._to_str(stdout).strip()
1217 | 
1218 |     @cached_property
1219 |     def _debian_version(self) -> str:
1220 |         try:
1221 |             with open(
1222 |                 os.path.join(self.etc_dir, "debian_version"), encoding="ascii"
1223 |             ) as fp:
1224 |                 return fp.readline().rstrip()
1225 |         except FileNotFoundError:
1226 |             return ""
1227 | 
1228 |     @staticmethod
1229 |     def _parse_uname_content(lines: Sequence[str]) -> Dict[str, str]:
1230 |         if not lines:
1231 |             return {}
1232 |         props = {}
1233 |         match = re.search(r"^([^\s]+)\s+([\d\.]+)", lines[0].strip())
1234 |         if match:
1235 |             name, version = match.groups()
1236 | 
1237 |             # This is to prevent the Linux kernel version from
1238 |             # appearing as the 'best' version on otherwise
1239 |             # identifiable distributions.
1240 |             if name == "Linux":
1241 |                 return {}
1242 |             props["id"] = name.lower()
1243 |             props["name"] = name
1244 |             props["release"] = version
1245 |         return props
1246 | 
1247 |     @staticmethod
1248 |     def _to_str(bytestring: bytes) -> str:
1249 |         encoding = sys.getfilesystemencoding()
1250 |         return bytestring.decode(encoding)
1251 | 
1252 |     @cached_property
1253 |     def _distro_release_info(self) -> Dict[str, str]:
1254 |         """
1255 |         Get the information items from the specified distro release file.
1256 | 
1257 |         Returns:
1258 |             A dictionary containing all information items.
1259 |         """
1260 |         if self.distro_release_file:
1261 |             # If it was specified, we use it and parse what we can, even if
1262 |             # its file name or content does not match the expected pattern.
1263 |             distro_info = self._parse_distro_release_file(self.distro_release_file)
1264 |             basename = os.path.basename(self.distro_release_file)
1265 |             # The file name pattern for user-specified distro release files
1266 |             # is somewhat more tolerant (compared to when searching for the
1267 |             # file), because we want to use what was specified as best as
1268 |             # possible.
1269 |             match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
1270 |         else:
1271 |             try:
1272 |                 basenames = [
1273 |                     basename
1274 |                     for basename in os.listdir(self.etc_dir)
1275 |                     if basename not in _DISTRO_RELEASE_IGNORE_BASENAMES
1276 |                     and os.path.isfile(os.path.join(self.etc_dir, basename))
1277 |                 ]
1278 |                 # We sort for repeatability in cases where there are multiple
1279 |                 # distro specific files; e.g. CentOS, Oracle, Enterprise all
1280 |                 # containing `redhat-release` on top of their own.
1281 |                 basenames.sort()
1282 |             except OSError:
1283 |                 # This may occur when /etc is not readable but we can't be
1284 |                 # sure about the *-release files. Check common entries of
1285 |                 # /etc for information. If they turn out to not be there the
1286 |                 # error is handled in `_parse_distro_release_file()`.
1287 |                 basenames = _DISTRO_RELEASE_BASENAMES
1288 |             for basename in basenames:
1289 |                 match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
1290 |                 if match is None:
1291 |                     continue
1292 |                 filepath = os.path.join(self.etc_dir, basename)
1293 |                 distro_info = self._parse_distro_release_file(filepath)
1294 |                 # The name is always present if the pattern matches.
1295 |                 if "name" not in distro_info:
1296 |                     continue
1297 |                 self.distro_release_file = filepath
1298 |                 break
1299 |             else:  # the loop didn't "break": no candidate.
1300 |                 return {}
1301 | 
1302 |         if match is not None:
1303 |             distro_info["id"] = match.group(1)
1304 | 
1305 |         # CloudLinux < 7: manually enrich info with proper id.
1306 |         if "cloudlinux" in distro_info.get("name", "").lower():
1307 |             distro_info["id"] = "cloudlinux"
1308 | 
1309 |         return distro_info
1310 | 
1311 |     def _parse_distro_release_file(self, filepath: str) -> Dict[str, str]:
1312 |         """
1313 |         Parse a distro release file.
1314 | 
1315 |         Parameters:
1316 | 
1317 |         * filepath: Path name of the distro release file.
1318 | 
1319 |         Returns:
1320 |             A dictionary containing all information items.
1321 |         """
1322 |         try:
1323 |             with open(filepath, encoding="utf-8") as fp:
1324 |                 # Only parse the first line. For instance, on SLES there
1325 |                 # are multiple lines. We don't want them...
1326 |                 return self._parse_distro_release_content(fp.readline())
1327 |         except OSError:
1328 |             # Ignore not being able to read a specific, seemingly version
1329 |             # related file.
1330 |             # See https://github.com/python-distro/distro/issues/162
1331 |             return {}
1332 | 
1333 |     @staticmethod
1334 |     def _parse_distro_release_content(line: str) -> Dict[str, str]:
1335 |         """
1336 |         Parse a line from a distro release file.
1337 | 
1338 |         Parameters:
1339 |         * line: Line from the distro release file. Must be a unicode string
1340 |                 or a UTF-8 encoded byte string.
1341 | 
1342 |         Returns:
1343 |             A dictionary containing all information items.
1344 |         """
1345 |         matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match(line.strip()[::-1])
1346 |         distro_info = {}
1347 |         if matches:
1348 |             # regexp ensures non-None
1349 |             distro_info["name"] = matches.group(3)[::-1]
1350 |             if matches.group(2):
1351 |                 distro_info["version_id"] = matches.group(2)[::-1]
1352 |             if matches.group(1):
1353 |                 distro_info["codename"] = matches.group(1)[::-1]
1354 |         elif line:
1355 |             distro_info["name"] = line.strip()
1356 |         return distro_info
1357 | 
1358 | 
1359 | _distro = LinuxDistribution()
1360 | 
1361 | 
1362 | def main() -> None:
1363 |     logger = logging.getLogger(__name__)
1364 |     logger.setLevel(logging.DEBUG)
1365 |     logger.addHandler(logging.StreamHandler(sys.stdout))
1366 | 
1367 |     parser = argparse.ArgumentParser(description="OS distro info tool")
1368 |     parser.add_argument(
1369 |         "--json", "-j", help="Output in machine readable format", action="store_true"
1370 |     )
1371 | 
1372 |     parser.add_argument(
1373 |         "--root-dir",
1374 |         "-r",
1375 |         type=str,
1376 |         dest="root_dir",
1377 |         help="Path to the root filesystem directory (defaults to /)",
1378 |     )
1379 | 
1380 |     args = parser.parse_args()
1381 | 
1382 |     if args.root_dir:
1383 |         dist = LinuxDistribution(
1384 |             include_lsb=False,
1385 |             include_uname=False,
1386 |             include_oslevel=False,
1387 |             root_dir=args.root_dir,
1388 |         )
1389 |     else:
1390 |         dist = _distro
1391 | 
1392 |     if args.json:
1393 |         logger.info(json.dumps(dist.info(), indent=4, sort_keys=True))
1394 |     else:
1395 |         logger.info("Name: %s", dist.name(pretty=True))
1396 |         distribution_version = dist.version(pretty=True)
1397 |         logger.info("Version: %s", distribution_version)
1398 |         distribution_codename = dist.codename()
1399 |         logger.info("Codename: %s", distribution_codename)
1400 | 
1401 | 
1402 | if __name__ == "__main__":
1403 |     main()
1404 | 
```
Page 143/168FirstPrevNextLast