Installation

This package is available on PyPI, so you can install the latest stable release with you favorite package manager:

Easiest way is to install uv, then add it to your project:

$ uv add extra-platforms

Or to install the CLI system-wide with uv tool:

$ uv tool install extra-platforms

pipx is a great way to install the CLI globally:

$ pipx install extra-platforms

You can install the latest stable release and its dependencies with a simple pip call:

$ python -m pip install extra-platforms

See also pip installation instructions.

Try it now

You can try Extra Platforms right now in your terminal, without installing any dependency or virtual env thanks to uvx:

$ uvx extra-platforms
$ uvx extra-platforms@9.0.1
$ uvx --from git+https://github.com/kdeldycke/extra-platforms -- extra-platforms
$ uvx --from file:///Users/me/code/extra-platforms -- extra-platforms

Try the library

You can also try the library itself in an interactive Python shell without installing anything on your system:

$ uvx --with extra-platforms python
>>> from extra_platforms import current_platform, BSD, UNIX, LINUX
>>> current_platform()
Platform(id='macos', name='macOS')
>>> current_platform() in BSD
True
>>> current_platform() in UNIX
True
>>> current_platform() in LINUX
False

Main dependencies

This is a graph of the default, main dependencies of the Python package:

        flowchart LR
    extra_platforms[["`extra-platforms`"]]

    subgraph grp_docs [--group docs]
        sphinx{{"`sphinx >=9.1`"}}
        click_extra{{"`click-extra >=7.5`"}}
        repomatic{{"`repomatic >=6.14`"}}
        pytest{{"`pytest >=8.2.1`"}}
        bump_my_version(["`bump-my-version`"])
        aiohttp(["`aiohttp`"])
        pygments(["`pygments`"])
        myst_parser{{"`myst-parser >=5`"}}
        requests{{"`requests`"}}
        typing_extensions(["`typing-extensions`"])
        furo{{"`furo >=2025.9.25`"}}
        pydantic(["`pydantic`"])
        click_0(["`click`"])
        httpx(["`httpx`"])
        pydriller(["`pydriller`"])
        wcmatch{{"`wcmatch >=10`"}}
        colorama(["`colorama`"])
        idna(["`idna`"])
        jinja2(["`jinja2`"])
        markdown_it_py(["`markdown-it-py`"])
        packaging(["`packaging`"])
        pydantic_settings(["`pydantic-settings`"])
        rich(["`rich`"])
        rich_click(["`rich-click`"])
        sphinxcontrib_mermaid{{"`sphinxcontrib-mermaid >=1.2.2`"}}
        yarl(["`yarl`"])
        aiosignal(["`aiosignal`"])
        anyio(["`anyio`"])
        beautifulsoup4(["`beautifulsoup4`"])
        certifi(["`certifi`"])
        docutils(["`docutils`"])
        httpcore(["`httpcore`"])
        lizard(["`lizard`"])
        pyyaml(["`pyyaml`"])
        typing_inspection(["`typing-inspection`"])
        vt_py(["`vt-py`"])
        accessible_pygments(["`accessible-pygments`"])
        boltons(["`boltons`"])
        cloup(["`cloup`"])
        frozenlist(["`frozenlist`"])
        gitdb(["`gitdb`"])
        gitpython(["`gitpython`"])
        mdit_py_plugins(["`mdit-py-plugins`"])
        multidict(["`multidict`"])
        pluggy(["`pluggy`"])
        prompt_toolkit(["`prompt-toolkit`"])
        propcache(["`propcache`"])
        py_walk(["`py-walk`"])
        pydantic_core(["`pydantic-core`"])
        pygments_ansi_color(["`pygments-ansi-color`"])
        pyproject_metadata(["`pyproject-metadata`"])
        questionary(["`questionary`"])
        sphinx_autodoc_typehints{{"`sphinx-autodoc-typehints >=2.4`"}}
        sphinx_basic_ng(["`sphinx-basic-ng`"])
        sphinx_copybutton{{"`sphinx-copybutton >=0.5.2`"}}
        sphinx_design{{"`sphinx-design >=0.6`"}}
        sphinx_issues{{"`sphinx-issues >=5`"}}
        sphinxext_opengraph{{"`sphinxext-opengraph >=0.13`"}}
        tabulate(["`tabulate`"])
        tomlkit(["`tomlkit`"])
        urllib3(["`urllib3`"])
        wcwidth(["`wcwidth`"])
        aiofiles(["`aiofiles`"])
        aiohappyeyeballs(["`aiohappyeyeballs`"])
        alabaster(["`alabaster`"])
        annotated_types(["`annotated-types`"])
        attrs(["`attrs`"])
        babel(["`babel`"])
        bracex(["`bracex`"])
        charset_normalizer(["`charset-normalizer`"])
        deepmerge(["`deepmerge`"])
        h11(["`h11`"])
        imagesize(["`imagesize`"])
        iniconfig(["`iniconfig`"])
        markupsafe(["`markupsafe`"])
        mdurl(["`mdurl`"])
        pathspec(["`pathspec`"])
        python_dotenv(["`python-dotenv`"])
        pytz(["`pytz`"])
        roman_numerals(["`roman-numerals`"])
        sly(["`sly`"])
        smmap(["`smmap`"])
        snowballstemmer(["`snowballstemmer`"])
        soupsieve(["`soupsieve`"])
        sphinxcontrib_applehelp(["`sphinxcontrib-applehelp`"])
        sphinxcontrib_devhelp(["`sphinxcontrib-devhelp`"])
        sphinxcontrib_htmlhelp(["`sphinxcontrib-htmlhelp`"])
        sphinxcontrib_jsmath(["`sphinxcontrib-jsmath`"])
        sphinxcontrib_qthelp(["`sphinxcontrib-qthelp`"])
        sphinxcontrib_serializinghtml(["`sphinxcontrib-serializinghtml`"])
        types_pytz(["`types-pytz`"])
    end

    subgraph grp_test [--group test]
        pytest_cov{{"`pytest-cov >=7`"}}
        pytest_xdist{{"`pytest-xdist >=3.7`"}}
        coverage{{"`coverage >=7.11`"}}
        tomli{{"`tomli >=2.3`"}}
        exceptiongroup(["`exceptiongroup`"])
        pytest_github_actions_annotate_failures{{"`pytest-github-actions-annotate-failures >=0.3`"}}
        pytest_randomly{{"`pytest-randomly >=4`"}}
        execnet(["`execnet`"])
        psutil(["`psutil`"])
    end

    subgraph grp_typing [--group typing]
        types_requests{{"`types-requests >=2.32.4.20250611`"}}
    end

    sphinx --> pygments
    sphinx ==> requests
    sphinx --> colorama
    sphinx --> jinja2
    sphinx --> packaging
    sphinx --> docutils
    sphinx --> alabaster
    sphinx --> babel
    sphinx --> imagesize
    sphinx --> roman_numerals
    sphinx --> snowballstemmer
    sphinx --> sphinxcontrib_applehelp
    sphinx --> sphinxcontrib_devhelp
    sphinx --> sphinxcontrib_htmlhelp
    sphinx --> sphinxcontrib_jsmath
    sphinx --> sphinxcontrib_qthelp
    sphinx --> sphinxcontrib_serializinghtml
    click_extra ==> sphinx
    click_extra --> extra_platforms
    click_extra --> pygments
    click_extra ==> requests
    click_extra --> click_0
    click_extra ==> wcmatch
    click_extra --> docutils
    click_extra --> boltons
    click_extra --> cloup
    click_extra --> pygments_ansi_color
    click_extra --> tabulate
    click_extra --> deepmerge
    repomatic --> extra_platforms
    repomatic ==> click_extra
    repomatic --> bump_my_version
    repomatic --> pydriller
    repomatic ==> wcmatch
    repomatic --> packaging
    repomatic --> pyyaml
    repomatic --> vt_py
    repomatic --> boltons
    repomatic --> py_walk
    repomatic --> pyproject_metadata
    repomatic --> tomlkit
    pytest --> pygments
    pytest --> colorama
    pytest --> packaging
    pytest ==> tomli
    pytest --> exceptiongroup
    pytest --> pluggy
    pytest --> iniconfig
    myst_parser ==> sphinx
    myst_parser --> jinja2
    myst_parser --> markdown_it_py
    myst_parser --> docutils
    myst_parser --> pyyaml
    myst_parser --> mdit_py_plugins
    requests --> idna
    requests --> certifi
    requests --> urllib3
    requests --> charset_normalizer
    furo ==> sphinx
    furo --> pygments
    furo --> beautifulsoup4
    furo --> accessible_pygments
    furo --> sphinx_basic_ng
    wcmatch --> bracex
    pytest_cov ==> pytest
    pytest_cov ==> coverage
    pytest_cov --> pluggy
    pytest_xdist ==> pytest
    pytest_xdist --> execnet
    pytest_xdist --> psutil
    sphinxcontrib_mermaid ==> sphinx
    sphinxcontrib_mermaid --> jinja2
    sphinxcontrib_mermaid --> pyyaml
    coverage ==> tomli
    pytest_github_actions_annotate_failures ==> pytest
    pytest_randomly ==> pytest
    sphinx_autodoc_typehints ==> sphinx
    sphinx_copybutton ==> sphinx
    sphinx_design ==> sphinx
    sphinx_issues ==> sphinx
    sphinxext_opengraph ==> sphinx
    types_requests --> urllib3
    bump_my_version --> pydantic
    bump_my_version --> click_0
    bump_my_version --> httpx
    bump_my_version ==> wcmatch
    bump_my_version --> pydantic_settings
    bump_my_version --> rich
    bump_my_version --> rich_click
    bump_my_version --> questionary
    bump_my_version --> tomlkit
    click_0 --> colorama
    pydriller --> lizard
    pydriller --> gitpython
    pydriller --> pytz
    pydriller --> types_pytz
    jinja2 --> markupsafe
    markdown_it_py --> mdurl
    beautifulsoup4 --> typing_extensions
    beautifulsoup4 --> soupsieve
    vt_py --> aiohttp
    vt_py --> aiofiles
    accessible_pygments --> pygments
    cloup --> click_0
    exceptiongroup --> typing_extensions
    mdit_py_plugins --> markdown_it_py
    py_walk --> sly
    pygments_ansi_color --> pygments
    pyproject_metadata --> packaging
    sphinx_basic_ng ==> sphinx
    tabulate --> wcwidth
    aiohttp --> yarl
    aiohttp --> aiosignal
    aiohttp --> frozenlist
    aiohttp --> multidict
    aiohttp --> propcache
    aiohttp --> aiohappyeyeballs
    aiohttp --> attrs
    pydantic --> typing_extensions
    pydantic --> typing_inspection
    pydantic --> pydantic_core
    pydantic --> annotated_types
    httpx --> idna
    httpx --> anyio
    httpx --> certifi
    httpx --> httpcore
    pydantic_settings --> pydantic
    pydantic_settings --> typing_inspection
    pydantic_settings --> python_dotenv
    rich --> pygments
    rich --> markdown_it_py
    rich_click --> click_0
    rich_click --> colorama
    rich_click --> rich
    lizard --> pygments
    lizard --> pathspec
    gitpython --> gitdb
    questionary --> prompt_toolkit
    yarl --> idna
    yarl --> multidict
    yarl --> propcache
    aiosignal --> typing_extensions
    aiosignal --> frozenlist
    anyio --> typing_extensions
    anyio --> idna
    httpcore --> certifi
    httpcore --> h11
    typing_inspection --> typing_extensions
    gitdb --> smmap
    prompt_toolkit --> wcwidth
    pydantic_core --> typing_extensions
    extra_platforms -.-> grp_docs
    extra_platforms -.-> grp_test
    extra_platforms -.-> grp_typing

    click accessible_pygments "https://pypi.org/project/accessible-pygments/" _blank
    click aiofiles "https://pypi.org/project/aiofiles/" _blank
    click aiohappyeyeballs "https://pypi.org/project/aiohappyeyeballs/" _blank
    click aiohttp "https://pypi.org/project/aiohttp/" _blank
    click aiosignal "https://pypi.org/project/aiosignal/" _blank
    click alabaster "https://pypi.org/project/alabaster/" _blank
    click annotated_types "https://pypi.org/project/annotated-types/" _blank
    click anyio "https://pypi.org/project/anyio/" _blank
    click attrs "https://pypi.org/project/attrs/" _blank
    click babel "https://pypi.org/project/babel/" _blank
    click beautifulsoup4 "https://pypi.org/project/beautifulsoup4/" _blank
    click boltons "https://pypi.org/project/boltons/" _blank
    click bracex "https://pypi.org/project/bracex/" _blank
    click bump_my_version "https://pypi.org/project/bump-my-version/" _blank
    click certifi "https://pypi.org/project/certifi/" _blank
    click charset_normalizer "https://pypi.org/project/charset-normalizer/" _blank
    click click_0 "https://pypi.org/project/click/" _blank
    click click_extra "https://pypi.org/project/click-extra/" _blank
    click cloup "https://pypi.org/project/cloup/" _blank
    click colorama "https://pypi.org/project/colorama/" _blank
    click coverage "https://pypi.org/project/coverage/" _blank
    click deepmerge "https://pypi.org/project/deepmerge/" _blank
    click docutils "https://pypi.org/project/docutils/" _blank
    click exceptiongroup "https://pypi.org/project/exceptiongroup/" _blank
    click execnet "https://pypi.org/project/execnet/" _blank
    click extra_platforms "https://pypi.org/project/extra-platforms/" _blank
    click frozenlist "https://pypi.org/project/frozenlist/" _blank
    click furo "https://pypi.org/project/furo/" _blank
    click gitdb "https://pypi.org/project/gitdb/" _blank
    click gitpython "https://pypi.org/project/gitpython/" _blank
    click h11 "https://pypi.org/project/h11/" _blank
    click httpcore "https://pypi.org/project/httpcore/" _blank
    click httpx "https://pypi.org/project/httpx/" _blank
    click idna "https://pypi.org/project/idna/" _blank
    click imagesize "https://pypi.org/project/imagesize/" _blank
    click iniconfig "https://pypi.org/project/iniconfig/" _blank
    click jinja2 "https://pypi.org/project/jinja2/" _blank
    click lizard "https://pypi.org/project/lizard/" _blank
    click markdown_it_py "https://pypi.org/project/markdown-it-py/" _blank
    click markupsafe "https://pypi.org/project/markupsafe/" _blank
    click mdit_py_plugins "https://pypi.org/project/mdit-py-plugins/" _blank
    click mdurl "https://pypi.org/project/mdurl/" _blank
    click multidict "https://pypi.org/project/multidict/" _blank
    click myst_parser "https://pypi.org/project/myst-parser/" _blank
    click packaging "https://pypi.org/project/packaging/" _blank
    click pathspec "https://pypi.org/project/pathspec/" _blank
    click pluggy "https://pypi.org/project/pluggy/" _blank
    click prompt_toolkit "https://pypi.org/project/prompt-toolkit/" _blank
    click propcache "https://pypi.org/project/propcache/" _blank
    click psutil "https://pypi.org/project/psutil/" _blank
    click py_walk "https://pypi.org/project/py-walk/" _blank
    click pydantic "https://pypi.org/project/pydantic/" _blank
    click pydantic_core "https://pypi.org/project/pydantic-core/" _blank
    click pydantic_settings "https://pypi.org/project/pydantic-settings/" _blank
    click pydriller "https://pypi.org/project/pydriller/" _blank
    click pygments "https://pypi.org/project/pygments/" _blank
    click pygments_ansi_color "https://pypi.org/project/pygments-ansi-color/" _blank
    click pyproject_metadata "https://pypi.org/project/pyproject-metadata/" _blank
    click pytest "https://pypi.org/project/pytest/" _blank
    click pytest_cov "https://pypi.org/project/pytest-cov/" _blank
    click pytest_github_actions_annotate_failures "https://pypi.org/project/pytest-github-actions-annotate-failures/" _blank
    click pytest_randomly "https://pypi.org/project/pytest-randomly/" _blank
    click pytest_xdist "https://pypi.org/project/pytest-xdist/" _blank
    click python_dotenv "https://pypi.org/project/python-dotenv/" _blank
    click pytz "https://pypi.org/project/pytz/" _blank
    click pyyaml "https://pypi.org/project/pyyaml/" _blank
    click questionary "https://pypi.org/project/questionary/" _blank
    click repomatic "https://pypi.org/project/repomatic/" _blank
    click requests "https://pypi.org/project/requests/" _blank
    click rich "https://pypi.org/project/rich/" _blank
    click rich_click "https://pypi.org/project/rich-click/" _blank
    click roman_numerals "https://pypi.org/project/roman-numerals/" _blank
    click sly "https://pypi.org/project/sly/" _blank
    click smmap "https://pypi.org/project/smmap/" _blank
    click snowballstemmer "https://pypi.org/project/snowballstemmer/" _blank
    click soupsieve "https://pypi.org/project/soupsieve/" _blank
    click sphinx "https://pypi.org/project/sphinx/" _blank
    click sphinx_autodoc_typehints "https://pypi.org/project/sphinx-autodoc-typehints/" _blank
    click sphinx_basic_ng "https://pypi.org/project/sphinx-basic-ng/" _blank
    click sphinx_copybutton "https://pypi.org/project/sphinx-copybutton/" _blank
    click sphinx_design "https://pypi.org/project/sphinx-design/" _blank
    click sphinx_issues "https://pypi.org/project/sphinx-issues/" _blank
    click sphinxcontrib_applehelp "https://pypi.org/project/sphinxcontrib-applehelp/" _blank
    click sphinxcontrib_devhelp "https://pypi.org/project/sphinxcontrib-devhelp/" _blank
    click sphinxcontrib_htmlhelp "https://pypi.org/project/sphinxcontrib-htmlhelp/" _blank
    click sphinxcontrib_jsmath "https://pypi.org/project/sphinxcontrib-jsmath/" _blank
    click sphinxcontrib_mermaid "https://pypi.org/project/sphinxcontrib-mermaid/" _blank
    click sphinxcontrib_qthelp "https://pypi.org/project/sphinxcontrib-qthelp/" _blank
    click sphinxcontrib_serializinghtml "https://pypi.org/project/sphinxcontrib-serializinghtml/" _blank
    click sphinxext_opengraph "https://pypi.org/project/sphinxext-opengraph/" _blank
    click tabulate "https://pypi.org/project/tabulate/" _blank
    click tomli "https://pypi.org/project/tomli/" _blank
    click tomlkit "https://pypi.org/project/tomlkit/" _blank
    click types_pytz "https://pypi.org/project/types-pytz/" _blank
    click types_requests "https://pypi.org/project/types-requests/" _blank
    click typing_extensions "https://pypi.org/project/typing-extensions/" _blank
    click typing_inspection "https://pypi.org/project/typing-inspection/" _blank
    click urllib3 "https://pypi.org/project/urllib3/" _blank
    click vt_py "https://pypi.org/project/vt-py/" _blank
    click wcmatch "https://pypi.org/project/wcmatch/" _blank
    click wcwidth "https://pypi.org/project/wcwidth/" _blank
    click yarl "https://pypi.org/project/yarl/" _blank

    style extra_platforms stroke-width:3px
    style click_extra stroke-width:3px
    style coverage stroke-width:3px
    style furo stroke-width:3px
    style myst_parser stroke-width:3px
    style pytest stroke-width:3px
    style pytest_cov stroke-width:3px
    style pytest_github_actions_annotate_failures stroke-width:3px
    style pytest_randomly stroke-width:3px
    style pytest_xdist stroke-width:3px
    style repomatic stroke-width:3px
    style requests stroke-width:3px
    style sphinx stroke-width:3px
    style sphinx_autodoc_typehints stroke-width:3px
    style sphinx_copybutton stroke-width:3px
    style sphinx_design stroke-width:3px
    style sphinx_issues stroke-width:3px
    style sphinxcontrib_mermaid stroke-width:3px
    style sphinxext_opengraph stroke-width:3px
    style tomli stroke-width:3px
    style types_requests stroke-width:3px
    style wcmatch stroke-width:3px

    style grp_docs fill:#546E7A20,stroke:#90A4AE
    style grp_test fill:#546E7A20,stroke:#90A4AE
    style grp_typing fill:#546E7A20,stroke:#90A4AE

    

Extra dependencies

For additional features, you may need to install extra dependencies.

For Pytest

Activate new fixtures and utilities for testing Click CLIs:

$ pip install extra-platforms[pytest]

Naming

Tip

I wanted to call this package platforms, but it’s already taken on PyPI. So I went with extra-platforms instead, to mark its affiliation with Click Extra.