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
- Pass both arguments explicitly: `android_platforms(api_level=33, abi='arm64_v8a')`.
- Parametrize the Android API level and ABI from your build config / target NDK settings rather than relying on host defaults.
- Guard the call site so `android_platforms()` is only invoked when actually targeting Android.
- 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
- Always pass `api_level` and `abi` explicitly when cross-targeting Android.
- Source both values from your NDK/build config, not the host.
- Guard the call site so Android tag generation only runs when targeting Android.
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
- invalid sysconfig.get_config_var('EXT_SUFFIX')
- Invalid wheel filename (compressed tag set components must b
- Cannot restore Tag from {state!r}
- Tag component {component!r} is not in sorted order per PEP 4
- name is invalid: {name!r}
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/dca8a8f604ce61ae.json.
Report an issue: GitHub.