Search code examples
pythonmacos

Python's "platform.mac_ver()" reports incorrect MacOS version


I'm using Python platform module to identify the MacOS version like this:

import platform
print(platform.mac_ver())

Output:

In [1]: import platform

In [2]: platform.mac_ver()
Out[2]: ('10.16', ('', '', ''), 'x86_64')

I have updated to BigSur and the version is incorrect, it should be 11.0.1

enter image description here

I looked at the source code of platform and it seems to parse a this file /System/Library/CoreServices/SystemVersion.plist to get the information. When reading this file from Python I get an incorrect version but from bash it is the correct one

Bash:

Amirs-MacBook-Pro:~ arossert$ cat /System/Library/CoreServices/SystemVersion.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ProductBuildVersion</key>
    <string>20B50</string>
    <key>ProductCopyright</key>
    <string>1983-2020 Apple Inc.</string>
    <key>ProductName</key>
    <string>macOS</string>
    <key>ProductUserVisibleVersion</key>
    <string>11.0.1</string>
    <key>ProductVersion</key>
    <string>11.0.1</string>
    <key>iOSSupportVersion</key>
    <string>14.2</string>
</dict>
</plist>

Python:

In [4]: print(open("/System/Library/CoreServices/SystemVersion.plist").read())
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ProductBuildVersion</key>
    <string>20B50</string>
    <key>ProductCopyright</key>
    <string>1983-2020 Apple Inc.</string>
    <key>ProductName</key>
    <string>Mac OS X</string>
    <key>ProductUserVisibleVersion</key>
    <string>10.16</string>
    <key>ProductVersion</key>
    <string>10.16</string>
    <key>iOSSupportVersion</key>
    <string>14.2</string>
</dict>
</plist>

What am I missing?

This is the output from the same ipython session

In [3]: print(open("/System/Library/CoreServices/SystemVersion.plist").read())
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ProductBuildVersion</key>
    <string>20B50</string>
    <key>ProductCopyright</key>
    <string>1983-2020 Apple Inc.</string>
    <key>ProductName</key>
    <string>Mac OS X</string>
    <key>ProductUserVisibleVersion</key>
    <string>10.16</string>
    <key>ProductVersion</key>
    <string>10.16</string>
    <key>iOSSupportVersion</key>
    <string>14.2</string>
</dict>
</plist>


In [4]: cat /System/Library/CoreServices/SystemVersion.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ProductBuildVersion</key>
    <string>20B50</string>
    <key>ProductCopyright</key>
    <string>1983-2020 Apple Inc.</string>
    <key>ProductName</key>
    <string>macOS</string>
    <key>ProductUserVisibleVersion</key>
    <string>11.0.1</string>
    <key>ProductVersion</key>
    <string>11.0.1</string>
    <key>iOSSupportVersion</key>
    <string>14.2</string>
</dict>
</plist>

Solution

  • In the Known Issues section of the Big Sur release notes, the following is present:

    Some third-party scripts might produce unexpected results due to the change in macOS version from 10.x to 11. (62477208)

    Workaround: Set SYSTEM_VERSION_COMPAT=1 in the calling environment, for example: $ SYSTEM_VERSION_COMPAT=1 legacy_script.pl

    There is also a rather extensive 3rd-party writeup at https://eclecticlight.co/2020/08/13/macos-version-numbering-isnt-so-simple/


    Applications compiled for Big Sur or later get back "11.0" as the operating system version.

    Applications compiled for earlier versions get "10.16". This is so logic that assumes 10 as the prefix will not break.

    The environment variable SYSTEM_VERSION_COMPAT can be used to control which version of the file is returned; SYSTEM_VERSION_COMPAT=0 cat /System/Library/CoreServices/SystemVersion.plist returns 11.0.1, whereas SYSTEM_VERSION_COMPAT=1 cat /System/Library/CoreServices/SystemVersion.plist returns 10.16. (Note that there should be a space, not a newline, between the assignment and the invocation of cat, such that the shell sees this as a transient environment variable assignment rather than the assignment of a non-exported shell variable).