:mod:`!platform` ---  Access to underlying platform's identifying data
======================================================================

.. module:: platform
   :synopsis: Retrieves as much platform identifying data as possible.

.. moduleauthor:: Marc-André Lemburg <mal@egenix.com>
.. sectionauthor:: Bjorn Pettersen <bpettersen@corp.fairisaac.com>

**Source code:** :source:`Lib/platform.py`

--------------

.. note::

   Specific platforms listed alphabetically, with Linux included in the Unix
   section.


Cross Platform
--------------


.. function:: architecture(executable=sys.executable, bits='', linkage='')

   Queries the given executable (defaults to the Python interpreter binary) for
   various architecture information.

   Returns a tuple ``(bits, linkage)`` which contain information about the bit
   architecture and the linkage format used for the executable. Both values are
   returned as strings.

   Values that cannot be determined are returned as given by the parameter presets.
   If bits is given as ``''``, the ``sizeof(pointer)`` (or
   ``sizeof(long)`` on Python version < 1.5.2) is used as indicator for the
   supported pointer size.

   The function relies on the system's :file:`file` command to do the actual work.
   This is available on most if not all Unix  platforms and some non-Unix platforms
   and then only if the executable points to the Python interpreter.  Reasonable
   defaults are used when the above needs are not met.

   .. note::

      On macOS (and perhaps other platforms), executable files may be
      universal files containing multiple architectures.

      To get at the "64-bitness" of the current interpreter, it is more
      reliable to query the :data:`sys.maxsize` attribute::

         is_64bits = sys.maxsize > 2**32


.. function:: machine()

   Returns the machine type, e.g. ``'AMD64'``. An empty string is returned if the
   value cannot be determined.


.. function:: node()

   Returns the computer's network name (may not be fully qualified!). An empty
   string is returned if the value cannot be determined.


.. function:: platform(aliased=False, terse=False)

   Returns a single string identifying the underlying platform with as much useful
   information as possible.

   The output is intended to be *human readable* rather than machine parseable. It
   may look different on different platforms and this is intended.

   If *aliased* is true, the function will use aliases for various platforms that
   report system names which differ from their common names, for example SunOS will
   be reported as Solaris.  The :func:`system_alias` function is used to implement
   this.

   Setting *terse* to true causes the function to return only the absolute minimum
   information needed to identify the platform.

   .. versionchanged:: 3.8
      On macOS, the function now uses :func:`mac_ver`, if it returns a
      non-empty release string, to get the macOS version rather than the darwin
      version.


.. function:: processor()

   Returns the (real) processor name, e.g. ``'amdk6'``.

   An empty string is returned if the value cannot be determined. Note that many
   platforms do not provide this information or simply return the same value as for
   :func:`machine`.  NetBSD does this.


.. function:: python_build()

   Returns a tuple ``(buildno, builddate)`` stating the Python build number and
   date as strings.


.. function:: python_compiler()

   Returns a string identifying the compiler used for compiling Python.


.. function:: python_branch()

   Returns a string identifying the Python implementation SCM branch.


.. function:: python_implementation()

   Returns a string identifying the Python implementation. Possible return values
   are: 'CPython', 'IronPython', 'Jython', 'PyPy'.


.. function:: python_revision()

   Returns a string identifying the Python implementation SCM revision.


.. function:: python_version()

   Returns the Python version as string ``'major.minor.patchlevel'``.

   Note that unlike the Python ``sys.version``, the returned value will always
   include the patchlevel (it defaults to 0).


.. function:: python_version_tuple()

   Returns the Python version as tuple ``(major, minor, patchlevel)`` of strings.

   Note that unlike the Python ``sys.version``, the returned value will always
   include the patchlevel (it defaults to ``'0'``).


.. function:: release()

   Returns the system's release, e.g. ``'2.2.0'`` or ``'NT'``. An empty string is
   returned if the value cannot be determined.


.. function:: system()

   Returns the system/OS name, such as ``'Linux'``, ``'Darwin'``, ``'Java'``,
   ``'Windows'``. An empty string is returned if the value cannot be determined.

   On iOS and Android, this returns the user-facing OS name (i.e, ``'iOS``,
   ``'iPadOS'`` or ``'Android'``). To obtain the kernel name (``'Darwin'`` or
   ``'Linux'``), use :func:`os.uname()`.

.. function:: system_alias(system, release, version)

   Returns ``(system, release, version)`` aliased to common marketing names used
   for some systems.  It also does some reordering of the information in some cases
   where it would otherwise cause confusion.


.. function:: version()

   Returns the system's release version, e.g. ``'#3 on degas'``. An empty string is
   returned if the value cannot be determined.

   On iOS and Android, this is the user-facing OS version. To obtain the
   Darwin or Linux kernel version, use :func:`os.uname()`.

.. function:: uname()

   Fairly portable uname interface. Returns a :func:`~collections.namedtuple`
   containing six attributes: :attr:`system`, :attr:`node`, :attr:`release`,
   :attr:`version`, :attr:`machine`, and :attr:`processor`.

   :attr:`processor` is resolved late, on demand.

   Note: the first two attribute names differ from the names presented by
   :func:`os.uname`, where they are named :attr:`sysname` and
   :attr:`nodename`.

   Entries which cannot be determined are set to ``''``.

   .. versionchanged:: 3.3
      Result changed from a tuple to a :func:`~collections.namedtuple`.

   .. versionchanged:: 3.9
      :attr:`processor` is resolved late instead of immediately.


Java Platform
-------------


.. function:: java_ver(release='', vendor='', vminfo=('','',''), osinfo=('','',''))

   Version interface for Jython.

   Returns a tuple ``(release, vendor, vminfo, osinfo)`` with *vminfo* being a
   tuple ``(vm_name, vm_release, vm_vendor)`` and *osinfo* being a tuple
   ``(os_name, os_version, os_arch)``. Values which cannot be determined are set to
   the defaults given as parameters (which all default to ``''``).

   .. deprecated-removed:: 3.13 3.15
      It was largely untested, had a confusing API,
      and was only useful for Jython support.


Windows Platform
----------------


.. function:: win32_ver(release='', version='', csd='', ptype='')

   Get additional version information from the Windows Registry and return a tuple
   ``(release, version, csd, ptype)`` referring to OS release, version number,
   CSD level (service pack) and OS type (multi/single processor). Values which
   cannot be determined are set to the defaults given as parameters (which all
   default to an empty string).

   As a hint: *ptype* is ``'Uniprocessor Free'`` on single processor NT machines
   and ``'Multiprocessor Free'`` on multi processor machines. The ``'Free'`` refers
   to the OS version being free of debugging code. It could also state ``'Checked'``
   which means the OS version uses debugging code, i.e. code that checks arguments,
   ranges, etc.

.. function:: win32_edition()

   Returns a string representing the current Windows edition, or ``None`` if the
   value cannot be determined.  Possible values include but are not limited to
   ``'Enterprise'``, ``'IoTUAP'``, ``'ServerStandard'``, and ``'nanoserver'``.

   .. versionadded:: 3.8

.. function:: win32_is_iot()

   Return ``True`` if the Windows edition returned by :func:`win32_edition`
   is recognized as an IoT edition.

   .. versionadded:: 3.8


macOS Platform
--------------

.. function:: mac_ver(release='', versioninfo=('','',''), machine='')

   Get macOS version information and return it as tuple ``(release, versioninfo,
   machine)`` with *versioninfo* being a tuple ``(version, dev_stage,
   non_release_version)``.

   Entries which cannot be determined are set to ``''``.  All tuple entries are
   strings.

iOS Platform
------------

.. function:: ios_ver(system='', release='', model='', is_simulator=False)

   Get iOS version information and return it as a
   :func:`~collections.namedtuple` with the following attributes:

   * ``system`` is the OS name; either ``'iOS'`` or ``'iPadOS'``.
   * ``release`` is the iOS version number as a string (e.g., ``'17.2'``).
   * ``model`` is the device model identifier; this will be a string like
     ``'iPhone13,2'`` for a physical device, or ``'iPhone'`` on a simulator.
   * ``is_simulator`` is a boolean describing if the app is running on a
     simulator or a physical device.

   Entries which cannot be determined are set to the defaults given as
   parameters.


Unix Platforms
--------------

.. function:: libc_ver(executable=sys.executable, lib='', version='', chunksize=16384)

   Tries to determine the libc version against which the file executable (defaults
   to the Python interpreter) is linked.  Returns a tuple of strings ``(lib,
   version)`` which default to the given parameters in case the lookup fails.

   Note that this function has intimate knowledge of how different libc versions
   add symbols to the executable is probably only usable for executables compiled
   using :program:`gcc`.

   The file is read and scanned in chunks of *chunksize* bytes.


Linux Platforms
---------------

.. function:: freedesktop_os_release()

   Get operating system identification from ``os-release`` file and return
   it as a dict. The ``os-release`` file is a `freedesktop.org standard
   <https://www.freedesktop.org/software/systemd/man/os-release.html>`_ and
   is available in most Linux distributions. A noticeable exception is
   Android and Android-based distributions.

   Raises :exc:`OSError` or subclass when neither ``/etc/os-release`` nor
   ``/usr/lib/os-release`` can be read.

   On success, the function returns a dictionary where keys and values are
   strings. Values have their special characters like ``"`` and ``$``
   unquoted. The fields ``NAME``, ``ID``, and ``PRETTY_NAME`` are always
   defined according to the standard. All other fields are optional. Vendors
   may include additional fields.

   Note that fields like ``NAME``, ``VERSION``, and ``VARIANT`` are strings
   suitable for presentation to users. Programs should use fields like
   ``ID``, ``ID_LIKE``, ``VERSION_ID``, or ``VARIANT_ID`` to identify
   Linux distributions.

   Example::

      def get_like_distro():
          info = platform.freedesktop_os_release()
          ids = [info["ID"]]
          if "ID_LIKE" in info:
              # ids are space separated and ordered by precedence
              ids.extend(info["ID_LIKE"].split())
          return ids

   .. versionadded:: 3.10


Android Platform
----------------

.. function:: android_ver(release="", api_level=0, manufacturer="", \
                          model="", device="", is_emulator=False)

   Get Android device information. Returns a :func:`~collections.namedtuple`
   with the following attributes. Values which cannot be determined are set to
   the defaults given as parameters.

   * ``release`` - Android version, as a string (e.g. ``"14"``).

   * ``api_level`` - API level of the running device, as an integer (e.g. ``34``
     for Android 14). To get the API level which Python was built against, see
     :func:`sys.getandroidapilevel`.

   * ``manufacturer`` - `Manufacturer name
     <https://developer.android.com/reference/android/os/Build#MANUFACTURER>`__.

   * ``model`` - `Model name
     <https://developer.android.com/reference/android/os/Build#MODEL>`__ –
     typically the marketing name or model number.

   * ``device`` - `Device name
     <https://developer.android.com/reference/android/os/Build#DEVICE>`__ –
     typically the model number or a codename.

   * ``is_emulator`` - ``True`` if the device is an emulator; ``False`` if it's
     a physical device.

   Google maintains a `list of known model and device names
   <https://storage.googleapis.com/play_public/supported_devices.html>`__.

   .. versionadded:: 3.13
