pypa/pip · error · TypeError

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

Error message

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

What it means

Raised as TypeError by android_platforms (tags.py:856-859) when the function is called on a host whose platform.system() is not 'Android' AND either api_level or abi is None. On a real Android device the values default from platform.android_ver() and sysconfig; on any other OS the caller must supply both explicitly, since there is no Android environment to read them from.

Solutions

  1. On non-Android hosts, always pass both api_level and abi, e.g. android_platforms(api_level=33, abi='arm64_v8a').
  2. Detect the target before calling: only rely on defaults when platform.system() == 'Android'.
  3. Centralize Android target configuration (API level + ABI) and inject it into the call site.
  4. Catch TypeError and prompt/configure the missing values from your build settings.

Example fix

# before (running on Linux/macOS)
android_platforms()  # TypeError: api_level and abi are required

# after - supply the Android target explicitly
android_platforms(api_level=33, abi='arm64_v8a')
Defensive patterns

Strategy: validation

Validate before calling

import platform
def android_args(api_level=None, abi=None):
    if platform.system() != 'Android':
        assert api_level is not None and abi is not None, 'api_level and abi required on non-Android'
    return api_level, abi

Try / catch

try:
    list(android_platforms())
except TypeError:
    list(android_platforms(api_level=33, abi='arm64_v8a'))

Prevention

When it happens

Trigger: android_platforms() called on Linux/macOS/Windows with no arguments; android_platforms(api_level=30) on macOS (abi missing); android_platforms(abi='arm64_v8a') on Linux (api_level missing); a cross-compilation script invoking it without args on the build host.

Common situations: Cross-compiling Android wheels on a non-Android build host; a CI job generating Android platform tags without passing the target API level/ABI; a generic tag-listing tool that calls android_platforms unconditionally.

Related errors


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

Appendix: source

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

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.

    .. versionadded:: 25.0
    """
    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 f399c37189)