Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams @matth Slightly more consistent output. i.e. platform.system() returns "Windows" instead of "win32" . sys.platform also contains "linux2" on old versions of Python while it contains just "linux" on newer ones. platform.system() has always returned just "Linux" . erb Jun 9, 2017 at 10:22 @baptistechéné, I know this has over an year since you asked, but as a comment won't hurt, I'll post it anyways :) So, the reason behind it is because it shows the kernel name. The same way Linux (the kernel) distros have many names (Ubuntu, Arch, Fedora among others), but it'll present itself as the kernel name, Linux. Darwin (a BSD-based Kernel), has its surrounding system, the macOS. I'm pretty sure apple did release Darwin as an open source code, but there's no other distro running over Darwin that I know of. Joao Paulo Rabelo Jan 30, 2019 at 12:05 @TooroSan os.uname() only exists for Unix systems. The Python 3 docs: docs.python.org/3/library/os.html Availability: recent flavors of Unix. Irving Moy Mar 22, 2020 at 21:49 So, yeah, I just ran platform.release() on my Windows 10 , and it definitely just gave me '8' . Maybe I installed python before upgrading, but really?? Codesmith Jun 8, 2017 at 13:35 I'd have thought it's more likely you upgraded from Windows 8 (vs. it being a clean install) and whatever Python looks up in the registry or whatever was left behind? OJFord Jan 30, 2018 at 20:53 The release lookup for python on Windows appears to use the Win32 api function GetVersionEx at its core. The notes at the top of this Microsoft article about that function could be relevant: msdn.microsoft.com/en-us/library/windows/desktop/… theferrit32 Mar 22, 2018 at 20:13 19.2.0 is the release version of Darwin that comes with Catalina 10.15.2: en.wikipedia.org/wiki/MacOS_Catalina#Release_history philshem Aug 21, 2020 at 13:28
import sys
if sys.platform.startswith("linux"):  # could be "linux", "linux2", "linux3", ...
    # linux
elif sys.platform == "darwin":
    # MAC OS X
elif os.name == "nt":
    # Windows, Cygwin, etc. (either 32-bit or 64-bit)
                Little problem: win64 does not exis: github.com/python/cpython/blob/master/Lib/platform.py. All Windows versions are win32.
– user136036
                Oct 9, 2020 at 13:52

Short Story

Use platform.system(). It returns Windows, Linux or Darwin (for OS X).

Long Story

There are three ways to get the OS in Python, each with its own pro and cons:

Method 1

>>> import sys
>>> sys.platform
'win32'  # could be 'linux', 'linux2, 'darwin', 'freebsd8' etc

How this works (source): Internally it calls OS APIs to get the name of the OS as defined by the OS. See here for various OS-specific values.

Pro: No magic, low level.

Con: OS version dependent, so best not to use directly.

Method 2

>>> import os
>>> os.name
'nt'  # for Linux and Mac it prints 'posix'

How this works (source): Internally it checks if Python has OS-specific modules called posix or nt.

Pro: Simple to check if it is a POSIX OS

Con: no differentiation between Linux or OS X.

Method 3

>>> import platform
>>> platform.system()
'Windows' # For Linux it prints 'Linux'. For Mac, it prints `'Darwin'

How this works (source): Internally it will eventually call internal OS APIs, get the OS version-specific name, like 'win32' or 'win16' or 'linux1' and then normalize to more generic names like 'Windows' or 'Linux' or 'Darwin' by applying several heuristics.

Pro: The best portable way for Windows, OS X, and Linux.

Con: Python folks must keep normalization heuristic up to date.

Summary

  • If you want to check if OS is Windows or Linux, or OS X, then the most reliable way is platform.system().
  • If you want to make OS-specific calls, but via built-in Python modules posix or nt, then use os.name.
  • If you want to get the raw OS name as supplied by the OS itself, then use sys.platform.
  • So much for "There should be one (and preferably only one) way to do things". However I believe this is the right answer. You would need to compare with titled OS names but it's not such an issue and will be more portable. – vincent-lg Apr 13, 2020 at 10:00 Note that in Python 3.10 , platform.system defaults to sys.platform if the os.uname throws an exception: github.com/python/cpython/blob/… – Heberto Mayorquin Aug 23, 2022 at 15:58

    I started a bit more systematic listing of what values you can expect using the various modules:

    Linux (64 bit) + WSL

                                x86_64            aarch64
                                ------            -------
    os.name                     posix             posix
    sys.platform                linux             linux
    platform.system()           Linux             Linux
    sysconfig.get_platform()    linux-x86_64      linux-aarch64
    platform.machine()          x86_64            aarch64
    platform.architecture()     ('64bit', '')     ('64bit', 'ELF')
    
  • I tried with Arch Linux and Linux Mint, but I got the same results
  • on Python 2, sys.platform is suffixed by the kernel version, e.g., linux2, and everything else stays identical
  • the same output on Windows Subsystem for Linux (I tried with Ubuntu 18.04 (Bionic Beaver) LTS), except platform.architecture() = ('64bit', 'ELF')
  • Windows (64 bit)

    (with 32-bit column running in the 32-bit subsystem)

    Official Python installer   64 bit                    32 bit
    -------------------------   -----                     -----
    os.name                     nt                        nt
    sys.platform                win32                     win32
    platform.system()           Windows                   Windows
    sysconfig.get_platform()    win-amd64                 win32
    platform.machine()          AMD64                     AMD64
    platform.architecture()     ('64bit', 'WindowsPE')    ('64bit', 'WindowsPE')
    msys2                       64 bit                     32 bit
    -----                       -----                     -----
    os.name                     posix                     posix
    sys.platform                msys                      msys
    platform.system()           MSYS_NT-10.0              MSYS_NT-10.0-WOW
    sysconfig.get_platform()    msys-2.11.2-x86_64        msys-2.11.2-i686
    platform.machine()          x86_64                    i686
    platform.architecture()     ('64bit', 'WindowsPE')    ('32bit', 'WindowsPE')
    msys2                       mingw-w64-x86_64-python3  mingw-w64-i686-python3
    -----                       ------------------------  ----------------------
    os.name                     nt                        nt
    sys.platform                win32                     win32
    platform.system()           Windows                   Windows
    sysconfig.get_platform()    mingw                     mingw
    platform.machine()          AMD64                     AMD64
    platform.architecture()     ('64bit', 'WindowsPE')    ('32bit', 'WindowsPE')
    Cygwin                      64 bit                    32 bit
    ------                      -----                     -----
    os.name                     posix                     posix
    sys.platform                cygwin                    cygwin
    platform.system()           CYGWIN_NT-10.0            CYGWIN_NT-10.0-WOW
    sysconfig.get_platform()    cygwin-3.0.1-x86_64       cygwin-3.0.1-i686
    platform.machine()          x86_64                    i686
    platform.architecture()     ('64bit', 'WindowsPE')    ('32bit', 'WindowsPE')
    

    Some remarks:

  • there is also distutils.util.get_platform() which is identical to `sysconfig.get_platform
  • Anaconda on Windows is the same as the official Python Windows installer
  • I don't have a Mac nor a true 32-bit system and was not motivated to do it online
  • To compare with your system, simply run this script:

    from __future__ import print_function
    import os
    import sys
    import platform
    import sysconfig
    print("os.name                      ",  os.name)
    print("sys.platform                 ",  sys.platform)
    print("platform.system()            ",  platform.system())
    print("sysconfig.get_platform()     ",  sysconfig.get_platform())
    print("platform.machine()           ",  platform.machine())
    print("platform.architecture()      ",  platform.architecture())
                    On latest MSYS2, MinGW64 reports sys.platform as win32 like your reported, but MSYS2 and UCRT64 report cygwin but not msys.
    – Paebbels
                    Jan 8, 2022 at 18:52
    

    You can also use sys.platform if you already have imported sys and you don't want to import another module

    >>> import sys
    >>> sys.platform
    'linux2'
                    Does on of the approaches have any advantages, besides having to or not to import another module?
    – matth
                    Nov 7, 2016 at 14:41
                    Scoping is the main advantage. You want as few global variable names  as possible. When you already have "sys" as a global name, you shouldn't add another one. But if you don't use "sys" yet, using "_platform" might be more descriptive and less likely to collide with another meaning.
    – sanderd17
                    Dec 21, 2016 at 9:01
    

    If you want user readable data, but still detailed, you can use platform.platform():

    >>> import platform
    >>> platform.platform()
    'Linux-3.3.0-8.fc16.x86_64-x86_64-with-fedora-16-Verne'
    

    Here are a few different possible calls you can make to identify where you are. linux_distribution and dist are removed in recent Python versions.

    import platform
    import sys
    def linux_distribution():
        return platform.linux_distribution()
      except:
        return "N/A"
    def dist():
        return platform.dist()
      except:
        return "N/A"
    print("""Python version: %s
    dist: %s
    linux_distribution: %s
    system: %s
    machine: %s
    platform: %s
    uname: %s
    version: %s
    mac_ver: %s
    """ % (
    sys.version.split('\n'),
    str(dist()),
    linux_distribution(),
    platform.system(),
    platform.machine(),
    platform.platform(),
    platform.uname(),
    platform.version(),
    platform.mac_ver(),
    

    The outputs of this script ran on a few different systems (Linux, Windows, Solaris, and macOS) and architectures (x86, x64, Itanium, PowerPC, and SPARC) is available at OS_flavor_name_version.

    Ubuntu 12.04 server (Precise Pangolin), for example, gives:

    Python version: ['2.6.5 (r265:79063, Oct  1 2012, 22:04:36) ', '[GCC 4.4.3]']
    dist: ('Ubuntu', '10.04', 'lucid')
    linux_distribution: ('Ubuntu', '10.04', 'lucid')
    system: Linux
    machine: x86_64
    platform: Linux-2.6.32-32-server-x86_64-with-Ubuntu-10.04-lucid
    uname: ('Linux', 'xxx', '2.6.32-32-server', '#62-Ubuntu SMP Wed Apr 20 22:07:43 UTC 2011', 'x86_64', '')
    version: #62-Ubuntu SMP Wed Apr 20 22:07:43 UTC 2011
    mac_ver: ('', ('', '', ''), '')
                    DeprecationWarning: dist() and linux_distribution() functions are deprecated in Python 3.5
    – Boris Verkhovskiy
                    Dec 27, 2019 at 4:57
    

    Use platform.system()

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

    import platform
    system = platform.system().lower()
    is_windows = system == 'windows'
    is_linux = system == 'linux'
    is_mac = system == 'darwin'
                    How can I get the name of my distro? For example, if I'm running Arch, how can I get Arch?
    – dio
                    Jul 25, 2021 at 17:30
    

    I am using the WLST tool that comes with WebLogic, and it doesn't implement the platform package.

    wls:/offline> import os
    wls:/offline> print os.name
    wls:/offline> import sys
    wls:/offline> print sys.platform
    'java1.5.0_11'
    

    Apart from patching the system javaos.py (issue with os.system() on Windows Server 2003 with JDK 1.5) (which I can't do, I have to use WebLogic out of the box), this is what I use:

    def iswindows():
      os = java.lang.System.getProperty( "os.name" )
      return "win" in os.lower()
    

    For Jython the only way to get the OS name I found is to check the os.name Java property (I tried with sys, os and platform modules for Jython 2.5.3 on Windows XP):

    def get_os_platform():
        """return platform name, but for Jython it uses os.name Java property"""
        ver = sys.platform.lower()
        if ver.startswith('java'):
            import java.lang
            ver = java.lang.System.getProperty("os.name").lower()
        print('platform: %s' % (ver))
        return ver
                    Why watch out? Can you elaborate? Preferably in the answer. (But ********* ********* ********* WITHOUT ********* ********* ********* "Edit:", "Update:", or similar - the answer should appear as if it was written today).
    – Peter Mortensen
                    Mar 25 at 18:15
                    Welcome on SO, here, it is a good practice to explain why to use your solution and not just how. That will make your answer more valuable and help further reader to have a better understanding of how you do it. I also suggest that you have a look on our FAQ : stackoverflow.com/faq.
    – ForceMagic
                    Nov 9, 2012 at 22:03
    

    Here is an easy and simple-to-understand Pythonic way to detect the OS in code. It was tested on Python 3.7.

    from sys import platform
    class UnsupportedPlatform(Exception):
    if "linux" in platform:
        print("linux")
    elif "darwin" in platform:
        print("mac")
    elif "win" in platform:
        print("windows")
    else:
        raise UnsupportedPlatform
                    If this code is ever refactored by someone not understanding the structure of the if, this could lead to a false detection of macos because win is included in darwin. A startswidth would be less problematic.
    – cansik
                    Dec 25, 2021 at 17:42
                    If you are refactoring code and you haven't mastered If statements you probably have bigger fish to fry.
    – robmsmt
                    Jan 2, 2022 at 17:33
                    If possible, changing an if branch should not lead to a false positive. This concept is called clean code.
    – cansik
                    Jan 4, 2022 at 14:06
    

    If you not looking for the kernel version, etc., but looking for the Linux distribution, you may want to use the following.

    In Python 2.6 and later:

    >>> import platform
    >>> print platform.linux_distribution()
    ('CentOS Linux', '6.0', 'Final')
    >>> print platform.linux_distribution()[0]
    CentOS Linux
    >>> print platform.linux_distribution()[1]
    

    In Python 2.4:

    >>> import platform
    >>> print platform.dist()
    ('centos', '6.0', 'Final')
    >>> print platform.dist()[0]
    centos
    >>> print platform.dist()[1]
    

    Obviously, this will work only if you are running this on Linux. If you want to have a more generic script across platforms, you can mix this with code samples given in other answers.

    Also os.uname() is not available on windows: docs.python.org/2/library/os.html#os.uname Availability: recent flavors of Unix. – ccpizza Oct 24, 2017 at 20:26

    You can also use only the platform module without importing the os module to get all the information.

    >>> import platform
    >>> platform.os.name
    'posix'
    >>> platform.uname()
    ('Darwin', 'mainframe.local', '15.3.0', 'Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64', 'x86_64', 'i386')
    

    A nice and tidy layout for reporting purpose can be achieved using this line:

    for i in zip(['system', 'node', 'release', 'version', 'machine', 'processor'], platform.uname()):print i[0], ':', i[1]
    

    That gives this output:

    system : Darwin
    node : mainframe.local
    release : 15.3.0
    version : Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64
    machine : x86_64
    processor : i386
    

    Usually the operating system version is missing, but you should know if you are running Windows, Linux or Mac, a platform-independent way is to use this test:

    In []: for i in [platform.linux_distribution(), platform.mac_ver(), platform.win32_ver()]:
       ....:     if i[0]:
       ....:         print 'Version: ', i[0]
                    This is problematic if you are on a Mac since platform.system() returns "Darwin" on a Mac and "Darwin".lower().find("win") = 3.
    – mishaF
                    Apr 19, 2013 at 15:10
    

    Check the available tests with module platform and print the answer out for your system:

    import platform
    print dir(platform)
    for x in dir(platform):
        if x[0].isalnum():
                result = getattr(platform, x)()
                print "platform." + x + ": " + result
            except TypeError:
                continue
    # This module contains functions to determine the basic type of
    # OS we are running on.
    # Contrary to the functions in the `os` and `platform` modules,
    # these allow to identify the actual basic OS,
    # no matter whether running on the `python` or `jython` interpreter.
    def is_linux():
            platform.linux_distribution()
            return True
        except:
            return False
    def is_windows():
            platform.win32_ver()
            return True
        except:
            return False
    def is_mac():
            platform.mac_ver()
            return True
        except:
            return False
    def name():
        if is_linux():
            return "Linux"
        elif is_windows():
            return "Windows"
        elif is_mac():
            return "Mac"
        else:
            return "<unknown>"
    

    Use like this:

    import os_identify
    print "My OS: " + os_identify.name()
    

    Use a simple Enum implementation like the following. There isn't any need for external libraries!

    import platform
    from enum import Enum
    class OS(Enum):
        def checkPlatform(osName):
            return osName.lower() == platform.system().lower()
        MAC = checkPlatform("darwin")
        LINUX = checkPlatform("linux")
        WINDOWS = checkPlatform("windows")  # I haven't tested this one
    

    Simply you can access them with the Enum value:

    if OS.LINUX.value:
        print("Cool. It is Linux")
    

    PS: It is Python 3.

    This a function I use to make adjustments on my code so it runs on Windows, Linux and macOS:

    import sys
    def get_os(osoptions={'linux':'linux', 'Windows':'win', 'macos':'darwin'}):
        Get OS to allow code specifics
        opsys = [k for k in osoptions.keys() if sys.platform.lower().find(osoptions[k].lower()) != -1]
            return opsys[0]
        except:
            return 'unknown_OS'
    

    You can look at the code in pyOSinfo which is part of the pip-date package, to get the most relevant OS information, as seen from your Python distribution.

    One of the most common reasons people want to check their OS is for terminal compatibility and if certain system commands are available. Unfortunately, the success of this checking is somewhat dependent on your Python installation and OS. For example, uname is not available on most Windows Python packages. The above Python program will show you the output of the most commonly used built-in functions, already provided by os, sys, platform, site.

    So the best way to get only the essential code is looking at that as an example.

    Please review Why not upload images of code/errors when asking a question? (e.g., "Images should only be used to illustrate problems that can't be made clear in any other way, such as to provide screenshots of a user interface.") and do the right thing (it covers answers as well). Thanks in advance. – Peter Mortensen Mar 25 at 19:27