{"record":{"id":"7fc0eb6a23dd8a86","repo":"pypa/pip","slug":"os-mkdir-not-supported-on-this-platform","errorCode":null,"errorMessage":"\"os.mkdir\" not supported on this platform.","messagePattern":"\"os\\.mkdir\" not supported on this platform\\.","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"critical","filePath":"src/pip/_vendor/pkg_resources/__init__.py","lineNumber":3510,"sourceCode":"    types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob))))\n    for t in types:\n        if t in registry:\n            return registry[t]\n    # _find_adapter would previously return None, and immediately be called.\n    # So we're raising a TypeError to keep backward compatibility if anyone depended on that behaviour.\n    raise TypeError(f\"Could not find adapter for {registry} and {ob}\")\n\n\ndef ensure_directory(path: StrOrBytesPath):\n    \"\"\"Ensure that the parent directory of `path` exists\"\"\"\n    dirname = os.path.dirname(path)\n    os.makedirs(dirname, exist_ok=True)\n\n\ndef _bypass_ensure_directory(path):\n    \"\"\"Sandbox-bypassing version of ensure_directory()\"\"\"\n    if not WRITE_SUPPORT:\n        raise OSError('\"os.mkdir\" not supported on this platform.')\n    dirname, filename = split(path)\n    if dirname and filename and not isdir(dirname):\n        _bypass_ensure_directory(dirname)\n        try:\n            mkdir(dirname, 0o755)\n        except FileExistsError:\n            pass\n\n\ndef split_sections(s: _NestedStr) -> Iterator[tuple[str | None, list[str]]]:\n    \"\"\"Split a string or iterable thereof into (section, content) pairs\n\n    Each ``section`` is a stripped version of the section header (\"[section]\")\n    and each ``content`` is a list of stripped lines excluding blank lines and\n    comment-only lines.  If there are any such lines before the first section\n    header, they're returned in a first ``section`` of ``None``.\n    \"\"\"\n    section = None","sourceCodeStart":3492,"sourceCodeEnd":3528,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/pkg_resources/__init__.py#L3492-L3528","documentation":"Raised as OSError in _bypass_ensure_directory() at line 3510 when WRITE_SUPPORT is False. WRITE_SUPPORT is set to False when `from os import mkdir, rename, unlink` raises ImportError (line 82-88), which happens on platforms that lack these OS primitives — most notably Google App Engine Standard Environment's Python 2 sandbox.","triggerScenarios":"Any code path that triggers _bypass_ensure_directory (a sandbox-bypassing mkdir) on a platform where os.mkdir/os.rename/os.unlink are not importable. This is checked at import time and propagated as OSError at runtime.","commonSituations":"Running pkg_resources on Google App Engine Standard (Python 2 sandbox) or other restricted sandboxes; embedded Python environments with stripped OS modules; very old or minimal Python builds.","solutions":["If on Google App Engine, upgrade to Python 3 runtime which has full OS support.","Use a runtime/environment that provides os.mkdir, os.rename, os.unlink.","Avoid code paths that require resource extraction / directory creation on restricted platforms.","Pre-install/extract resources before deploying to the sandbox."],"exampleFix":"// before: running on GAE Python 2 sandbox\nfrom pkg_resources import resource_filename\nresource_filename('pkg', 'data.txt')  # OSError: os.mkdir not supported\n\n// after: deploy with resources pre-extracted, or move to Python 3 runtime\nimport os\nif os.environ.get('GAE_VERSION'):\n    data = bundled_data  # pre-bundled at deploy time\nelse:\n    from pkg_resources import resource_filename\n    data = open(resource_filename('pkg', 'data.txt')).read()","handlingStrategy":"type-guard","validationCode":"from pip._vendor.pkg_resources import WRITE_SUPPORT\ndef can_extract_resources() -> bool:\n    return bool(WRITE_SUPPORT)","typeGuard":"import sys\ndef has_write_support() -> bool:\n    try:\n        from os import mkdir, rename, unlink\n        return True\n    except ImportError:\n        return False\n","tryCatchPattern":"from pip._vendor.pkg_resources import WRITE_SUPPORT\nif not WRITE_SUPPORT:\n    # use pre-bundled data instead of extraction\n    data = bundled_data\nelse:\n    from pkg_resources import resource_filename\n    data = open(resource_filename('pkg', 'data.txt')).read()\n","preventionTips":["Pre-bundle resources when deploying to sandboxed platforms like GAE Standard Python 2.","Check WRITE_SUPPORT before attempting resource extraction.","Upgrade to Python 3 runtime on restricted platforms for full OS support."],"tags":["platform","sandbox","gae","write-support","os"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}