Skip to main content

Lib/platform.py

cpython 3.14 @ ab2d84fe1023/Lib/platform.py

platform answers the basic question of "what machine is this code running on". It exposes individual accessor functions (system, node, release, version, machine, processor) and a unified uname() call that returns all six values together as a uname_result namedtuple. The module normalises platform strings across Linux, macOS, Windows, and a handful of Unix variants so callers get consistent output regardless of the underlying OS APIs.

Python build information is available through a parallel set of functions. python_version() returns the dotted version string, python_implementation() returns "CPython" or "PyPy" etc., python_compiler() returns the compiler string from sys.version, and python_build() returns the build number and date. Together these let runtime tools report exactly which Python is executing without parsing sys.version manually.

Linux distribution identification went through a significant change between Python 3.7 and 3.8. The old linux_distribution() function (removed in 3.8) read /etc/lsb-release and distro-specific files. The current code reads /etc/os-release and /usr/lib/os-release, which is the freedesktop.org standard supported by all modern distributions. The raw key-value pairs from that file are exposed through freedesktop_os_release().

Map

LinesSymbolRolegopy
1-80imports, _cache, DEV_NULLModule header, result cache dict, sentinel constants
81-220uname, uname_resultCore OS fingerprint: wraps os.uname / platform.uname
221-380system, node, release, version, machine, processorIndividual uname field accessors, cached via uname()
381-530python_implementation, python_version, python_version_tuple, python_build, python_compiler, python_branch, python_revisionPython build metadata extracted from sys attributes
531-700platform, _platformHuman-readable platform summary string, alias table
701-880freedesktop_os_release, _parse_os_release/etc/os-release reader for Linux distro info
881-1050win32_ver, win32_edition, win32_is_iotWindows registry and ctypes queries
1051-1250mac_ver, java_ver, architecturemacOS, Jython, and ELF/PE binary architecture probes

Reading

uname and uname_result (lines 81 to 220)

cpython 3.14 @ ab2d84fe1023/Lib/platform.py#L81-220

uname_result is a collections.namedtuple subclass with six fields: system, node, release, version, machine, processor. The processor field is not part of POSIX uname(2) so it is obtained separately via os.environ.get('PROCESSOR_IDENTIFIER') on Windows or a fallback to machine on other platforms. Results are cached in the module-level _uname_cache variable after the first call.

# Lib/platform.py ~line 130
_uname_cache = None

def uname():
global _uname_cache
if _uname_cache is not None:
return _uname_cache
...
system, node, release, version, machine, processor = info
_uname_cache = uname_result(system, node, release, version,
machine, processor)
return _uname_cache

Individual field accessors (lines 221 to 380)

cpython 3.14 @ ab2d84fe1023/Lib/platform.py#L221-380

Each of the six primary accessors is a one-liner that delegates to uname(). They exist as separate functions because uname was added later and many callers already depend on the individual names. The pattern is uniform across all six:

# ~line 240
def system():
return uname().system

def node():
return uname().node

def release():
return uname().release

def machine():
return uname().machine

def processor():
return uname().processor

Python build metadata (lines 381 to 530)

cpython 3.14 @ ab2d84fe1023/Lib/platform.py#L381-530

python_implementation checks sys.implementation.name (available from Python 3.3) and title-cases the result, mapping "cpython" to "CPython" and so on. python_version returns sys.version_info formatted as a dotted string. python_build extracts the build number and date from sys.version by parsing the parenthesised metadata that CPython embeds in that string.

# ~line 400
def python_implementation():
return sys.implementation.name.capitalize()
# CPython normalises to 'CPython' via the capitalize call

def python_version():
return '%d.%d.%d' % sys.version_info[:3]

def python_build():
return sys.version.split('\n')[1].strip(' ()').split(' ', 1)

freedesktop_os_release: Linux distro detection (lines 701 to 880)

cpython 3.14 @ ab2d84fe1023/Lib/platform.py#L701-880

freedesktop_os_release reads /etc/os-release, falling back to /usr/lib/os-release, and parses the shell-style KEY="value" lines into a plain dict. Quote stripping and backslash-escape handling follow the os-release(5) specification. The function raises OSError if neither file exists, which callers can catch to detect non-Linux platforms or containers without the file.

# ~line 760
def freedesktop_os_release():
for candidate in ('/etc/os-release', '/usr/lib/os-release'):
try:
with open(candidate, encoding='utf-8') as f:
return _parse_os_release(f)
except OSError:
pass
raise OSError('No os-release file found')

def _parse_os_release(f):
result = {}
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
k, _, v = line.partition('=')
result[k.strip()] = v.strip().strip('"').replace('\\"', '"')
return result

architecture: ELF and PE binary probe (lines 1051 to 1250)

cpython 3.14 @ ab2d84fe1023/Lib/platform.py#L1051-1250

architecture determines whether the running interpreter (or any specified executable) is a 32-bit or 64-bit binary. On Unix it calls file(1) via subprocess and parses its output for the strings 32-bit / 64-bit and the linkage type (ELF, dynamic, static). On Windows it reads the PE header directly from the executable bytes. The function returns a two-tuple (bits, linkage) such as ('64bit', 'ELF').

# ~line 1100
def architecture(executable=sys.executable, bits='', linkage=''):
...
if sys.platform == 'win32':
# Read PE header at offset 0x3C
with open(executable, 'rb') as f:
...
else:
try:
output = subprocess.check_output(['file', executable],
stderr=subprocess.DEVNULL)
fileout = output.decode('latin-1')
except (OSError, subprocess.CalledProcessError):
fileout = ''
if '32-bit' in fileout:
bits = '32bit'
elif '64-bit' in fileout:
bits = '64bit'
return bits, linkage

gopy mirror

Not yet ported.