PEP 11 Explained: How Python Decides Which Platforms It Supports

Python runs on a remarkable range of operating systems and hardware architectures. But that breadth of support does not happen by accident, and it does not last forever. PEP 11 is the document that governs exactly how the CPython development team decides which platforms are officially supported, how they are deprecated when support becomes unsustainable, and when they are dropped entirely. Understanding this document is not just a governance exercise. It is a window into one of the hardest recurring problems in open source: how to allocate finite human attention across an expanding universe of possible targets.

Every platform CPython supports represents a contract. Not a legal one, but a social one. When a platform appears in the Tier 1 or Tier 2 tables, the CPython core team is making an implicit promise to thousands of downstream users and hundreds of library maintainers that their code will continue to work there. Breaking that promise has cascading effects across the packaging ecosystem, CI infrastructure, deployment pipelines, and the trust relationship between the language and its community. PEP 11 exists to make those promises explicit and the process of revoking them transparent.

If you have ever wondered why Python 3.9 dropped support for Windows 7 or why a certain Linux distribution stopped receiving official CPython builds, the answer lives in PEP 11. Understanding this proposal helps you make informed decisions about deployment targets, long-term project planning, and which Python versions to pin when you need to support legacy infrastructure. This article walks through every major aspect of PEP 11, with enough depth to make the concepts stick.

What Is PEP 11 and Why Does It Exist

PEP 11 was originally authored by Martin von Lowis and has been maintained and updated by the CPython core development team over the years. Its full title is "Removing support for little-used platforms," and that title tells you most of what you need to know about its motivation. The proposal establishes a formal, documented process for how CPython handles platform support so that decisions are transparent, predictable, and fair to both users and contributors.

Before PEP 11, platform support decisions were informal and ad hoc. A platform might be dropped without warning simply because no one was actively maintaining the relevant code, or a new platform might be added without any clear expectations about long-term upkeep. PEP 11 changed that by creating a structured framework with defined criteria and a staged process that gives platform users time to respond before support disappears.

It is worth being precise about scope here. PEP 11 applies specifically to CPython, the reference implementation of Python maintained at python.org. Other implementations such as PyPy, Jython, and MicroPython have their own policies about which platforms they target. When people say "Python supports X," they usually mean CPython supports X, and PEP 11 is the document that governs that claim.

Note

PEP 11 is a living document. It is updated regularly as platforms are added, deprecated, or removed. You can always find the current version at peps.python.org/pep-0011. The table of supported platforms in the official document is the authoritative reference.

The core problem PEP 11 solves is one of maintainability. Every platform CPython supports requires someone to write and maintain platform-specific code, run a build machine or CI environment for that platform, and fix bugs that only appear on that platform. These are real costs measured in contributor time and attention. A platform that nobody is actively using or maintaining becomes a liability rather than an asset. PEP 11 provides the mechanism to recognize that situation and act on it responsibly.

There is a deeper tension at work here that is worth examining. Open source projects face a version of the tragedy of the commons when it comes to platform support. A company that deploys Python on an exotic architecture benefits enormously from that support but may never contribute a single line of code or hour of buildbot maintenance to keep it working. Meanwhile, the small group of core developers who do maintain the platform carry the entire burden. PEP 11's tier system is a governance response to this asymmetry. By making the cost of support visible and assigning specific maintainers to each platform, it converts an invisible public good into a named responsibility. That shift matters because it creates accountability. When a buildbot goes dark, there is a specific person or organization whose absence is noticed.

This governance model also reflects a broader truth about software sustainability. Languages and runtimes cannot support everything indefinitely. The computing landscape changes faster than volunteer contributor bandwidth can track. New architectures emerge (RISC-V, ARM server chips, WebAssembly runtimes), while legacy platforms fade (Solaris, HP-UX, Windows XP). PEP 11 gives CPython a framework to respond to these shifts without pretending that every platform is equally important or equally resourced. It is a practical acknowledgment that saying "we support this" should mean something verifiable, not just aspirational.

The Three Tiers of Platform Support

One of the most important contributions of PEP 11 to CPython's governance is its tiered support model. Not all platforms are equal, and the tier system reflects that reality explicitly rather than pretending every listed platform receives the same level of care.

Tier 1: Fully Supported

Tier 1 platforms are those where CPython must work. The CPython build system is tested against these platforms on every commit using official CI infrastructure. If a change breaks a Tier 1 platform, that change cannot be merged. Tier 1 represents the gold standard of support: if you are running Python on a Tier 1 platform, the core developers are actively ensuring it works correctly.

As of recent Python releases, Tier 1 platforms include 64-bit Linux on x86-64 (the dominant server and developer workstation architecture), Windows 64-bit on x86-64, and macOS on both x86-64 and Apple Silicon (arm64). These are the platforms where the overwhelming volume of Python code is written and deployed, which is why they receive this level of commitment.

Tier 2: Supported With Buildbot Coverage

Tier 2 platforms are those that have a buildbot — an automated build and test machine — contributing results to the CPython build farm. The CPython team does not necessarily maintain these buildbots directly; they are often operated by volunteers or organizations with a stake in that platform. The key requirement is that the buildbot must be kept up to date and must be actively monitored.

For a platform to remain in Tier 2, there must be someone willing to fix build failures when they occur. If a change breaks a Tier 2 platform and no one steps forward to fix it within a reasonable timeframe, the platform may be moved to a lower tier or deprecated. Tier 2 support means "we will try not to break you, and we expect you to let us know if we do."

Tier 2 covers a wider range of operating systems and architectures, including various Linux distributions on less common architectures, certain BSD variants, and older versions of operating systems that are still in widespread use but are not the primary targets for development.

Tier 3: Best Effort

Tier 3 platforms are those that CPython is known to run on, or is believed to run on, but where there is no active CI coverage. The code may compile and the tests may pass, but nobody is systematically verifying this on every commit. Tier 3 support is essentially community-maintained. If you care about a Tier 3 platform, the expectation is that you will test it yourself and report issues — and ideally submit fixes.

Pro Tip

When evaluating a deployment target for a long-running project, always check whether your target OS and architecture appears in the Tier 1 or Tier 2 list for the Python version you plan to use. A Tier 3 platform is not a guarantee of stability across minor Python releases.

How a Platform Gets Deprecated

Deprecation is the formal signal that support for a platform will end in a future Python release. PEP 11 prescribes a specific process to ensure this does not happen silently or without warning.

The trigger for deprecation is usually one of three things: the platform's operating system or distribution has itself reached end of life and is no longer receiving security updates, the buildbot for the platform has gone dark and no one has stepped up to replace it, or the platform-specific code in CPython has become a maintenance burden without corresponding benefit to users.

When a platform is nominated for deprecation, the process typically works as follows. First, a notice is issued to the python-dev mailing list and announced in the CPython issue tracker. This gives the community — including companies and individuals who may rely on that platform — an opportunity to respond. Specifically, someone can step forward and agree to maintain a buildbot and actively support the platform going forward. If no one volunteers within a reasonable period, the deprecation proceeds.

The deprecation itself is announced in the release notes for the Python version where it takes effect. This is important: the deprecation warning appears one full release cycle before support is actually removed. This means developers have at minimum one major Python release version to plan their migration. If Python 3.X deprecates support for a platform, that support will be removed in Python 3.(X+1) or a subsequent release, giving users a clear deadline.

# You can check the current platform at runtime using sys.platform
# This is useful for writing conditional code that handles platform differences

import sys

if sys.platform == 'win32':
    print("Running on Windows")
elif sys.platform == 'darwin':
    print("Running on macOS")
elif sys.platform.startswith('linux'):
    print("Running on Linux")
else:
    print(f"Running on an unrecognized platform: {sys.platform}")

# For more detailed information, use the platform module
import platform

print(platform.system())       # 'Windows', 'Linux', 'Darwin', etc.
print(platform.machine())      # 'x86_64', 'AMD64', 'arm64', etc.
print(platform.python_version()) # e.g., '3.13.0'

Once a platform is removed, CPython may still technically compile and run on it — the code does not change in a destructive way — but the core team makes no guarantees. Platform-specific workarounds and compatibility shims may be deleted, and build failures on the removed platform will not block new commits. Effectively, the platform is on its own.

What Happens to Unsupported Platforms

An important evolution in PEP 11 is the explicit policy around what happens to platforms that fall outside all three tiers. The November 2025 update by Petr Viktorin formalized the unsupported platforms policy, which clarifies that CPython does not treat a platform that loses Tier 3 support any worse than a platform that was never supported in the first place. The code base may still contain platform-specific fragments, and contributions for unsupported platforms are welcome as long as they pose a minimal maintenance burden and benefit substantially more people than just the contributor.

However — and this is the critical part — unsupported code that causes a maintenance burden or obstructs general improvements can be rejected or removed from the code base without a deprecation process. This is a different standard than what applies to tiered platforms. If you depend on an unsupported platform, the expectation is that you are prepared to maintain patches, test your own builds, and redistribute modified code to your users. The core team is not obligated to keep your platform working.

Build-Time Warnings for Unsupported Platforms

CPython's build system now emits warnings when someone attempts to build on a platform that is not listed in any support tier. On systems using autoconf, the configure script checks the platform triplet against the known tier lists and prints a clear message if the platform is unsupported, including a link to PEP 11 for more information. This was implemented through an enhancement to the configure script that makes platform support status visible at build time rather than something a developer has to look up separately. It is a practical example of PEP 11's philosophy of transparency — making the support relationship explicit rather than leaving it to guesswork.

Warning

If you are deploying Python on embedded systems, legacy industrial hardware, or enterprise environments with long OS refresh cycles, it is worth tracking PEP 11 updates closely. Being on a deprecated platform does not mean Python stops working immediately, but it does mean security patches and bug fixes may not reach you in future releases.

Notable Platforms Added and Removed Over Time

PEP 11 has a history that tracks the changing landscape of computing quite faithfully. Reading through the platforms that have been added and removed over the years is almost a tour through the evolution of operating systems and hardware.

Platforms That Were Dropped

Several platforms that were once important parts of the Python ecosystem have been removed through the PEP 11 process. IRIX, SGI's Unix variant that was once a major workstation platform in scientific computing and visual effects, was removed in Python 2.6. BeOS, the innovative operating system that inspired several modern OS concepts, was dropped even earlier. OS/2, which had a significant corporate user base in the 1990s, was removed in Python 2.6 as well.

Windows XP and Windows Vista support was removed as those operating systems reached end of life. Python 3.9 was the first release to drop Windows 7, making Python 3.8 the last version that could run on it. Windows 8.1 support was subsequently dropped in later releases. Each of these decisions followed the PEP 11 deprecation process, with notices given in advance and time allowed for community response. CPython's Windows support policy is now explicitly tied to Microsoft's support lifecycle: a new Python feature release will support all Windows versions whose extended support phase has not yet expired.

AtheOS, a hobby operating system with an ambitious feature set, was also once on the supported list before being removed when its development stalled. These historical examples illustrate that the deprecation process is not ideological — it applies equally to commercial operating systems from large vendors and to open-source projects from independent developers.

Platforms Added in Recent Years

The direction of platform support has not been entirely one of subtraction. Apple Silicon support was added to CPython with proper Tier 1 status starting in Python 3.11, recognizing that arm64 macOS had rapidly become one of the primary development platforms for a large portion of the Python community following Apple's transition away from Intel processors.

Various Linux on ARM configurations have also been elevated in their support tiers as ARM-based servers (particularly in cloud environments) and ARM-based developer machines have become more common. The Raspberry Pi and similar single-board computers have driven significant interest in Python on 32-bit and 64-bit ARM Linux configurations.

WebAssembly (WASM) is a newer area of interest. CPython began experimental support for running in browser environments and in WASI (WebAssembly System Interface) contexts. This represents a genuinely novel execution environment — one where Python is not running on a traditional operating system at all. The PEP 11 framework accommodates this by placing such platforms in lower tiers while the support matures. As of the current PEP 11 tables, WASI (wasm32-unknown-wasip1) has been elevated to Tier 2, while Emscripten (wasm32-unknown-emscripten) remains at Tier 3.

Mobile Platforms: iOS and Android

One of the more significant developments in CPython's platform landscape arrived with Python 3.13: official support for iOS and Android. PEP 730 (iOS) and PEP 738 (Android), both accepted by the Steering Council in early 2024, brought mobile platforms into the PEP 11 framework at Tier 3. This was a deliberate acknowledgment that mobile computing is no longer a niche concern — Android alone runs on roughly 70% of mobile devices worldwide, and Python's long-term relevance depends on being usable where developers and users spend their time.

Mobile platforms introduce constraints that desktop and server environments do not. iOS, for example, has no multiprocess support — fork and spawn exist in the API but do not function. Android uses the Bionic C library instead of glibc, which means platform-specific adaptations are required throughout CPython's build system. Neither platform is designed around a traditional command-line interpreter. The recommended deployment model on both iOS and Android is embedding libpython into a host application, not running a standalone python3 executable.

The Tier 3 status of these platforms means that CPython's test suite should pass on them, and the core team will accept patches to fix mobile-specific issues, but CI coverage is community-maintained and failures do not block releases. Projects like BeeWare and Kivy have maintained unofficial mobile support for years; the PEP 730/738 process formalized that work and brought it under the PEP 11 umbrella. PyPI has also been updated to accept iOS and Android wheel uploads, which opens the door for the broader package ecosystem to distribute mobile-compatible binaries.

Windows on ARM

Another addition worth noting is Windows on ARM64 (aarch64-pc-windows-msvc), which now appears in the PEP 11 Tier 3 table. As ARM-based Windows devices gain traction — particularly through devices like the Surface Pro X and laptops powered by Qualcomm Snapdragon chipsets — having Python available on native ARM Windows is increasingly relevant for developers working in those environments.

The Current Platform Tables

The official PEP 11 document now includes precise target triples for each tier along with the names of the core developers responsible for maintaining them. Here is a summary of the current state:

Tier 1 includes five target triples: aarch64-apple-darwin (Apple Silicon macOS with clang), aarch64-unknown-linux-gnu (64-bit ARM Linux with glibc/gcc), i686-pc-windows-msvc (32-bit Windows), x86_64-pc-windows-msvc (64-bit Windows), and x86_64-unknown-linux-gnu (64-bit x86 Linux with glibc/gcc). Failures on these platforms block every release.

Tier 2 currently covers four target triples: aarch64-unknown-linux-gnu with clang, wasm32-unknown-wasip1 (WebAssembly via WASI), x86_64-apple-darwin (Intel macOS), and x86_64-unknown-linux-gnu with clang. Each of these has at least two named core developer contacts, and failures must be fixed or reverted within 24 hours. Tier 2 failures also block releases.

Tier 3 is the broadest tier and includes Android (aarch64 and x86_64), Windows on ARM64, iOS (on-device and simulator), 32-bit ARM Linux (Raspberry Pi OS), 64-bit ARM Linux (Raspberry Pi OS), PowerPC64 LE Linux, s390x Linux, Emscripten (WASM in the browser), and FreeBSD on x86_64. Each has at least one core developer contact, but there is no response SLA and failures do not block releases.

Governance Philosophy

The underlying principle of PEP 11 is not to narrow Python's reach, but to make sure that the platforms Python claims to support receive genuine attention: active testing, responsive bug fixes, and identifiable maintainers who are accountable for keeping things working. That principle runs through every tier definition and every deprecation decision the CPython core team makes.

Reading Platform Information at Runtime

Understanding PEP 11 is not just an academic exercise. When you write Python code that needs to behave differently depending on the operating system or architecture it is running on, you are implicitly relying on the platform support guarantees that PEP 11 defines. Knowing how to query this information at runtime is a practical skill that connects directly to the policy.

The sys module is the primary entry point for platform information at a low level. The sys.platform attribute returns a string identifier for the current platform. The value 'win32' is returned on all versions of Windows regardless of whether the process is 32-bit or 64-bit. The value 'darwin' is returned on macOS. Linux returns 'linux' on Python 3 (it returned 'linux2' on Python 2, which is a common source of confusion in older codebases).

import sys
import platform
import struct

# Detect pointer size to distinguish 32-bit from 64-bit process
bits = struct.calcsize("P") * 8
print(f"Process is running in {bits}-bit mode")

# platform.machine() gives the hardware architecture
arch = platform.machine()
print(f"Machine architecture: {arch}")
# Common values: 'x86_64', 'AMD64', 'arm64', 'aarch64', 'i386'

# platform.system() gives the OS name in a clean format
os_name = platform.system()
print(f"Operating system: {os_name}")

# On Linux, you can get the distribution details
if sys.platform.startswith('linux'):
    try:
        os_release = platform.freedesktop_os_release()
        print(f"Distribution: {os_release.get('NAME', 'Unknown')}")
        print(f"Version: {os_release.get('VERSION_ID', 'Unknown')}")
    except AttributeError:
        # freedesktop_os_release was added in Python 3.10
        pass

# platform.version() gives the detailed OS version string
print(f"OS version: {platform.version()}")

The platform module provides higher-level utilities that are easier to work with than raw sys.platform strings. The platform.system() function returns clean strings like 'Windows', 'Linux', and 'Darwin'. The platform.machine() function returns the hardware architecture identifier. The platform.python_version() function returns the current Python version as a string.

For code that needs to handle platform differences, the cleanest approach is to write explicit conditional logic rather than trying to abstract it away prematurely. Here is a practical example of how you might handle a platform-specific file path operation:

import sys
from pathlib import Path

def get_config_directory() -> Path:
    """
    Return the appropriate configuration directory for the current platform.
    Follows platform conventions rather than hardcoding paths.
    """
    if sys.platform == 'win32':
        # Windows: use APPDATA environment variable
        import os
        appdata = os.environ.get('APPDATA', Path.home())
        return Path(appdata) / 'MyApplication'
    elif sys.platform == 'darwin':
        # macOS: use ~/Library/Application Support
        return Path.home() / 'Library' / 'Application Support' / 'MyApplication'
    else:
        # Linux and other Unix-like systems: follow XDG Base Directory spec
        import os
        xdg_config = os.environ.get('XDG_CONFIG_HOME', Path.home() / '.config')
        return Path(xdg_config) / 'myapplication'

config_dir = get_config_directory()
print(f"Config directory: {config_dir}")

Notice that the else branch in this example handles Linux and all other Unix-like platforms together. This is intentional and aligns with how PEP 11 thinks about platform families. FreeBSD, OpenBSD, and other Unix variants tend to behave similarly enough that they can share code paths, even if they have different support tier statuses in PEP 11.

What PEP 11 Means for Developers

For Python developers working on web applications, data analysis, or general automation, PEP 11 is background information that rarely demands direct attention. You are almost certainly on a Tier 1 platform, and platform support is not something you need to think about. But there are several contexts where PEP 11 becomes directly relevant to decisions you need to make — and the solutions available are more nuanced than simply checking a tier list.

Choosing Python Versions for Long-Lived Projects

If you are building software that needs to run on a specific operating system version — particularly in enterprise environments, embedded systems, or government infrastructure — you need to check whether that OS version is supported by the Python version you intend to use. An enterprise that is still running Windows Server 2012 R2, for example, is already navigating an environment where newer Python versions may not provide official support.

The PEP 11 platform table, combined with the Python version support lifecycle documented in PEP 602, gives you the full picture: which Python versions support which platforms, and for how long. These two documents together are essential reading for anyone making long-term platform decisions. Each Python feature release gets two years of active bug-fix support followed by three years of security-only fixes, for a total of five years. That means a platform deprecated in one release still has a usable Python version available for several years after the deprecation notice.

It is also worth noting that Python's versioning scheme may affect how you plan around deprecation timelines. PEP 2026, which proposed switching Python to calendar-based versioning (where Python 3.15 would have become Python 3.26), was rejected by the Steering Council in early 2025. Python will continue using sequential minor version numbers for the foreseeable future. This means you still need to map version numbers to calendar years manually when calculating support windows — which is exactly the kind of planning that makes PEP 11 and PEP 602 valuable reference documents.

Containerization as a Platform Abstraction Layer

One of the more sophisticated responses to platform deprecation is to decouple your Python runtime from the host operating system entirely. Docker and OCI-compliant container runtimes let you pin a specific Linux distribution, glibc version, and Python build inside a container image, regardless of what the host machine runs. If your deployment target is a legacy OS that CPython no longer supports at Tier 1, you can build a container image based on a supported base (such as a manylinux-compliant image) and deploy that container on top of the legacy host's kernel. The Python process inside the container sees a fully supported environment even if the host is running an older or unsupported platform.

This approach has limits. Containers add operational complexity, and not every deployment context supports them — embedded systems, scientific instruments, and air-gapped industrial networks may not have container runtimes available. But for cloud, server, and CI/CD contexts, containerization is one of the cleanest ways to sidestep the consequences of a platform falling out of PEP 11 support. It is worth building container-native deployment into your architecture from the start if you anticipate running on platforms whose support status may shift during your project's lifetime.

WebAssembly as a Portability Escape Hatch

WebAssembly (WASM) represents a genuinely different approach to the platform support problem. Rather than compiling CPython for each target platform, WASM compiles it once into a portable binary format that runs on any conformant WASM runtime. CPython already has WASI support at Tier 2 and Emscripten support at Tier 3. Tools like Pyodide bring a full CPython interpreter to the browser, while WASI-based runtimes like Wasmtime and WasmEdge allow server-side WASM execution with near-native performance.

For developers building tools that need to work in environments where you cannot control the host platform — browser-based data analysis tools, edge computing functions, or plugin systems embedded in other applications — WASM sidesteps PEP 11's platform matrix entirely. A single WASM binary runs on x86, ARM, RISC-V, or any other architecture that has a WASM runtime. The tradeoff is that WASM's system interface (WASI) is still maturing, Python's C extension ecosystem does not fully translate to WASM yet, and performance for compute-heavy workloads lags behind native compilation. But the trajectory is clear: Docker now supports WASM workloads alongside traditional containers, and the CNCF ecosystem is investing heavily in WASM as a deployment target. If your use case tolerates the current limitations, building for WASM today gives you a platform-agnostic foundation that becomes more capable with each WASI specification update.

The Mobile Platform Strategy

With iOS and Android now in PEP 11's Tier 3, the question for Python developers is no longer whether mobile support exists, but how to leverage it effectively. The BeeWare project's Briefcase tool can package Python applications as native iOS IPAs and Android APKs, and PyPI now accepts wheels for both platforms. Anaconda's open source team has driven official Android binary artifacts into the Python 3.14 release, and iOS binaries are following closely behind. The cibuildwheel project now supports Android build targets, which means CI pipelines can generate mobile wheels alongside desktop ones.

The deployment model on mobile is fundamentally different from desktop or server Python. You embed libpython into a host application rather than running a standalone interpreter. The fork system call does not work on iOS. Android uses the Bionic C library instead of glibc. These constraints mean that not every Python package works on mobile out of the box — packages with C extensions need to be cross-compiled, and anything that relies on multiprocessing, subprocess calls, or POSIX-specific file system behavior may need adaptation. Before committing to a mobile Python deployment, audit your dependency tree against the mobile wheel availability tracker that BeeWare maintains, and test on real devices early in the development cycle.

Building a Platform-Aware CI/CD Pipeline

A more structural solution to PEP 11 platform risk is to build platform awareness directly into your CI/CD infrastructure. Rather than testing only on your primary development platform and hoping for the best, construct a test matrix that reflects the PEP 11 tier landscape for every platform you intend to support. GitHub Actions, GitLab CI, and other platforms now support macOS ARM runners, Linux ARM64 runners, and even WASM test environments. Mapping your CI matrix to PEP 11 tiers lets you catch platform-specific regressions before they reach production, and it gives you early warning when a platform you depend on starts accumulating test failures — which is often the first signal that support is degrading.

For organizations that need to support Tier 3 or unsupported platforms, contributing a buildbot to the CPython build farm is the highest-leverage action available. A buildbot is not a trivial commitment — it requires a dedicated machine, network connectivity, and someone willing to respond to build failures — but it is the mechanism by which a platform moves from "best effort" to "actively maintained." If your business depends on Python working on a specific platform, the cost of maintaining a buildbot is almost certainly less than the cost of discovering that a new Python release breaks your deployment after the fact.

Contributing to CPython

If you are interested in contributing to CPython itself, PEP 11 defines what level of responsibility comes with adding or maintaining platform support. Adding a new platform to Tier 2 or Tier 1 is not just a code change — it is a commitment to maintain a buildbot, respond to build failures, and keep the platform working across future releases. PEP 11 makes this explicit, which helps set expectations for both the contributor and the core team.

If you are maintaining a buildbot for an existing platform and it goes dark — for example, because a cloud instance expired or a physical machine failed — the community expects you to either restore it promptly or announce that you are stepping back from that responsibility. PEP 11 provides the framework for what happens next: the platform moves down in tier or begins the deprecation process.

Writing Cross-Platform Libraries

Library authors who want their code to work on a wide range of platforms need to be aware of which platforms are in which tiers. Writing code that relies on a Tier 3 platform behaving consistently is a risk. Testing against it in your own CI is advisable if you want to claim support. If you depend on platform-specific behavior that only exists on a deprecated platform, you are taking on technical debt that will eventually need to be paid.

For libraries with C extensions, the cross-compilation story is becoming more viable but requires deliberate engineering. Tools like crossenv, cibuildwheel, and Maturin (for Rust-based Python extensions) now support cross-compilation to mobile and WASM targets. If you maintain a popular library, adding mobile and WASM wheels to your release pipeline positions your package for the next wave of Python deployment targets rather than waiting for users to request it after the fact. NumPy, Pandas, and other scientific Python packages are already working through this process with BeeWare's support.

Pro Tip

When publishing a package to PyPI, the python_requires field in your pyproject.toml lets you specify which Python versions your package supports. If your package uses platform-specific functionality, the classifiers field lets you declare which operating systems it is intended for. Keeping these in sync with PEP 11's tier designations helps users make informed decisions about whether your package will work for them. Now that PyPI accepts iOS and Android wheel uploads, library maintainers can extend their packaging matrix to include mobile targets using cibuildwheel's cross-compilation support — a step that positions packages for the growing mobile Python ecosystem without waiting for user demand to force the issue.

Packaging and Binary Distribution

When distributing pre-compiled Python packages — wheels, in the modern Python packaging ecosystem — the platform tag embedded in the wheel filename is directly tied to PEP 11 concepts. A wheel tagged cp313-cp313-manylinux_2_17_x86_64 tells you it was built for CPython 3.13 on a Linux distribution that uses glibc 2.17 or later on x86-64 hardware. Understanding which platform targets to build wheels for requires knowing which platforms your users are on, which in turn reflects the PEP 11 support tier landscape. Proper virtual environment setup and packaging hygiene become essential when working across multiple target platforms.

The manylinux platform tag deserves special mention here. It was developed precisely to address the fragmentation of Linux distributions while still providing binary wheels that work reliably. The PEP 11 framework and the manylinux specification work together to make binary Python package distribution on Linux feasible at scale.

Key Takeaways

  1. PEP 11 is the governing document for CPython platform support: It defines which operating systems and hardware architectures are officially supported, at what level, and how support is removed when it is no longer sustainable. More fundamentally, it converts an invisible public good (platform compatibility) into a named, accountable responsibility.
  2. The three-tier system reflects real differences in support commitment: Tier 1 platforms must work on every commit; Tier 2 platforms are tested via community-operated buildbots with a 24-hour fix-or-revert SLA; Tier 3 platforms are best-effort with no CI guarantees. Knowing which tier your deployment target falls into helps you assess risk realistically.
  3. Mobile platforms are now part of the framework: iOS and Android were added as Tier 3 platforms in Python 3.13 through PEP 730 and PEP 738. Python 3.14 shipped official Android binary artifacts, and iOS binaries are expected to follow. PyPI accepts mobile wheel uploads, and cibuildwheel supports Android build targets, making the mobile packaging ecosystem functional rather than theoretical.
  4. Containerization and WASM offer platform abstraction strategies: When your deployment target is at risk of losing PEP 11 support, Docker containers let you run a supported Linux environment on top of an unsupported host. WASM goes further by producing a single portable binary that runs on any conformant runtime regardless of host architecture. Both strategies let you decouple your Python runtime from the host platform's support status.
  5. Deprecation always comes with advance notice: No platform is silently dropped. The process requires a public announcement at least one release cycle before removal, giving users time to migrate or step up to maintain the platform themselves.
  6. Unsupported does not mean hostile: Platforms outside all three tiers can still have code in the CPython repository, and patches are welcome. But unsupported code that creates a maintenance burden can be removed without a deprecation process. If you rely on an unsupported platform, you are expected to maintain your own builds and patches.
  7. Platform support is a community responsibility: A platform stays in Tier 2 only as long as someone is actively maintaining a buildbot for it. If your business depends on Python running on a specific platform, contributing a buildbot is the highest-leverage action available — and almost certainly cheaper than discovering a broken deployment after the fact.
  8. Build platform awareness into your CI/CD pipeline: Mapping your test matrix to PEP 11 tiers catches platform-specific regressions before production. For library authors, extending build pipelines to include mobile and WASM targets positions packages for the next generation of Python deployment contexts.
  9. CPython now warns at build time on unsupported platforms: The configure script checks your platform against the PEP 11 tier tables and emits a warning if your target is not officially supported. This makes the support relationship visible before you invest time in a full build.
  10. PEP 11 affects packaging decisions: Wheel platform tags, python_requires classifiers, and binary distribution strategies all connect back to the platform support landscape that PEP 11 defines. Cross-compilation tools like cibuildwheel and Maturin are expanding to cover mobile and WASM targets, creating a packaging ecosystem that matches the broadening platform tier tables.

PEP 11 might not be the glamorous corner of the Python ecosystem, but it is one of the foundational documents that makes Python's reliability across diverse environments possible. From ARM servers in cloud data centers to iPhones in people's pockets, from WebAssembly runtimes in browsers to Raspberry Pi boards on workbenches, PEP 11 is the contract that defines what "Python runs here" means in practice. It is a good-faith agreement between the CPython core team and the broader community: we will tell you in advance what we support, we will give you warning before we stop, and we will give you the opportunity to keep a platform alive if you are willing to put in the work.

But PEP 11 is also a case study in something larger: how open source projects manage the tension between ambition and sustainability. Supporting more platforms means reaching more users, but it also means spreading finite contributor attention thinner. The tier system, the buildbot requirement, the deprecation process with advance notice — these are not bureaucratic overhead. They are the mechanisms that let a volunteer-driven project make credible promises at scale. For anyone building on Python, understanding how those promises are made and maintained is not just useful context. It is the kind of structural knowledge that separates developers who react to platform problems from those who anticipate them.