pypa/pip · error · TypeError

on non-Android platforms, the api_level and abi arguments ar

Error message

on non-Android platforms, the api_level and abi arguments are required

What it means

Raised by `android_platforms(api_level, abi)` in `packaging.tags` when the host is not Android (i.e. `platform.system() != 'Android'`) and either `api_level` or `abi` is `None`. On Android, the defaults are inferred from `platform.android_ver()` and `sysconfig.get_platform()`; off-Android there is no such host state to infer, so both arguments must be supplied explicitly to produce valid Android platform tags like `android_33_arm64_v8a`.

Source

Thrown at src/pip/_vendor/packaging/tags.py:745


def android_platforms(
    api_level: int | None = None, abi: str | None = None
) -> Iterator[str]:
    """
    Yields the :attr:`~Tag.platform` tags for Android. If this function is invoked on
    non-Android platforms, the ``api_level`` and ``abi`` arguments are required.

    :param int api_level: The maximum `API level
        <https://developer.android.com/tools/releases/platforms>`__ to return. Defaults
        to the current system's version, as returned by ``platform.android_ver``.
    :param str abi: The `Android ABI <https://developer.android.com/ndk/guides/abis>`__,
        e.g. ``arm64_v8a``. Defaults to the current system's ABI , as returned by
        ``sysconfig.get_platform``. Hyphens and periods will be replaced with
        underscores.
    """
    if platform.system() != "Android" and (api_level is None or abi is None):
        raise TypeError(
            "on non-Android platforms, the api_level and abi arguments are required"
        )

    if api_level is None:
        # Python 3.13 was the first version to return platform.system() == "Android",
        # and also the first version to define platform.android_ver().
        api_level = platform.android_ver().api_level  # type: ignore[attr-defined]

    if abi is None:
        abi = sysconfig.get_platform().split("-")[-1]
    abi = _normalize_string(abi)

    # 16 is the minimum API level known to have enough features to support CPython
    # without major patching. Yield every API level from the maximum down to the
    # minimum, inclusive.
    min_api_level = 16
    for ver in range(api_level, min_api_level - 1, -1):
        yield f"android_{ver}_{abi}"

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Pass both arguments explicitly: `android_platforms(api_level=33, abi='arm64_v8a')`.
  2. Parametrize the Android API level and ABI from your build config / target NDK settings rather than relying on host defaults.
  3. Guard the call site so `android_platforms()` is only invoked when actually targeting Android.
  4. If on Android but still hitting it, upgrade to Python 3.13+ where `platform.system() == 'Android'` and `platform.android_ver()` exist.

Example fix

// before
from pip._vendor.packaging.tags import android_platforms
plats = list(android_platforms())  # raises on desktop

# after
from pip._vendor.packaging.tags import android_platforms
plats = list(android_platforms(api_level=33, abi='arm64_v8a'))
Defensive patterns

Strategy: validation

Validate before calling

import platform

def android_platforms_safe(api_level=None, abi=None):
    if platform.system() != 'Android' and (api_level is None or abi is None):
        raise ValueError('api_level and abi are required when not running on Android')
    from pip._vendor.packaging.tags import android_platforms
    return list(android_platforms(api_level=api_level, abi=abi))

Try / catch

from pip._vendor.packaging.tags import android_platforms

try:
    plats = list(android_platforms(api_level=api_level, abi=abi))
except TypeError as e:
    if 'api_level and abi' in str(e):
        raise ValueError('Provide api_level and abi when targeting Android off-device') from e
    raise

Prevention

When it happens

Trigger: Calling `android_platforms()` (or a code path that feeds it, such as a cross-compiling resolver) on Linux/macOS/Windows without passing both `api_level` and `abi`. The guard is `platform.system() != 'Android' and (api_level is None or abi is None)`.

Common situations: Cross-building wheels for Android from a desktop CI runner; migrating from a docs example that omitted the args; assuming defaults work everywhere; running tests for an Android-packaging tool on a developer laptop.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/dca8a8f604ce61ae.json. Report an issue: GitHub.