pypa/pip · error · RuntimeError

should only be used on Unix

Error message

should only be used on Unix

What it means

platformdirs defines a win32-only stub for getuid() that raises RuntimeError('should only be used on Unix') whenever sys.platform == 'win32'. The Unix module's getuid (os.getuid) does not exist on Windows, so the stub stands in to fail loudly instead of producing an AttributeError.

Source

Thrown at src/pip/_vendor/platformdirs/unix.py:23

import os
import sys
from configparser import ConfigParser
from functools import cached_property
from pathlib import Path
from tempfile import gettempdir
from typing import TYPE_CHECKING, NoReturn

from ._xdg import XDGMixin
from .api import PlatformDirsABC

if TYPE_CHECKING:
    from collections.abc import Iterator

if sys.platform == "win32":

    def getuid() -> NoReturn:
        msg = "should only be used on Unix"
        raise RuntimeError(msg)

else:
    from os import getuid


class _UnixDefaults(PlatformDirsABC):  # ruff:ignore[too-many-public-methods]
    """Default directories for Unix/Linux without XDG environment variable overrides.

    The XDG env var handling is in :class:`~platformdirs._xdg.XDGMixin`.

    """

    @cached_property
    def _use_site(self) -> bool:
        return self.use_site_for_root and getuid() == 0

    @property
    def user_data_dir(self) -> str:

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Use the top-level platformdirs API (platformdirs.user_data_dir etc.) which selects the correct backend for the current OS.
  2. Guard Unix-only logic with 'if sys.platform != "win32"' before calling getuid/Unix-specific methods.
  3. If you must detect a user id cross-platform, use a helper that falls back (e.g. getpass) on Windows.

Example fix

# before
from pip._vendor.platformdirs.unix import getuid
uid = getuid()  # RuntimeError on Windows

# after
import sys
if sys.platform != 'win32':
    from os import getuid
    uid = getuid()
else:
    uid = None
Defensive patterns

Strategy: type-guard

Validate before calling

import sys
if sys.platform == 'win32':
    raise RuntimeError('getuid() is Unix-only; use a different code path')
from os import getuid
uid = getuid()

Type guard

def is_unix() -> bool:
    import sys
    return sys.platform != 'win32'

Try / catch

try:
    uid = getuid()
except RuntimeError as e:
    if 'should only be used on Unix' in str(e):
        uid = None
    raise

Prevention

When it happens

Trigger: Importing/using the Unix platformdirs backend (or calling getuid()) on a Windows interpreter where sys.platform == 'win32'; the conditional at import time binds the stub instead of os.getuid.

Common situations: Cross-platform code that imports platformdirs.unix explicitly instead of using the platform-agnostic entry point, or calling os.getuid-derived logic on Windows where no real uid exists.

Related errors


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