@@ -496,6 +496,30 @@ def mac_ver(release='', versioninfo=('', '', ''), machine=''):
496496 # If that also doesn't work return the default values
497497 return release , versioninfo , machine
498498
499+
500+ # A namedtuple for iOS version information.
501+ IOSVersionInfo = collections .namedtuple (
502+ "IOSVersionInfo" ,
503+ ["system" , "release" , "model" , "is_simulator" ]
504+ )
505+
506+
507+ def ios_ver (system = "" , release = "" , model = "" , is_simulator = False ):
508+ """Get iOS version information, and return it as a namedtuple:
509+ (system, release, model, is_simulator).
510+
511+ If values can't be determined, they are set to values provided as
512+ parameters.
513+ """
514+ if sys .platform == "ios" :
515+ import _ios_support
516+ result = _ios_support .get_platform_ios ()
517+ if result is not None :
518+ return IOSVersionInfo (* result )
519+
520+ return IOSVersionInfo (system , release , model , is_simulator )
521+
522+
499523def _java_getprop (name , default ):
500524 """This private helper is deprecated in 3.13 and will be removed in 3.15"""
501525 from java .lang import System
@@ -654,7 +678,7 @@ def _platform(*args):
654678 if cleaned == platform :
655679 break
656680 platform = cleaned
657- while platform [- 1 ] == '-' :
681+ while platform and platform [- 1 ] == '-' :
658682 platform = platform [:- 1 ]
659683
660684 return platform
@@ -695,7 +719,7 @@ def _syscmd_file(target, default=''):
695719 default in case the command should fail.
696720
697721 """
698- if sys .platform in ( 'dos' , 'win32' , 'win16' ) :
722+ if sys .platform in { 'dos' , 'win32' , 'win16' , 'ios' , 'tvos' , 'watchos' } :
699723 # XXX Others too ?
700724 return default
701725
@@ -859,6 +883,14 @@ def get_OpenVMS():
859883 csid , cpu_number = vms_lib .getsyi ('SYI$_CPU' , 0 )
860884 return 'Alpha' if cpu_number >= 128 else 'VAX'
861885
886+ # On the iOS simulator, os.uname returns the architecture as uname.machine.
887+ # On device it returns the model name for some reason; but there's only one
888+ # CPU architecture for iOS devices, so we know the right answer.
889+ def get_ios ():
890+ if sys .implementation ._multiarch .endswith ("simulator" ):
891+ return os .uname ().machine
892+ return 'arm64'
893+
862894 def from_subprocess ():
863895 """
864896 Fall back to `uname -p`
@@ -1018,6 +1050,10 @@ def uname():
10181050 system = 'Android'
10191051 release = android_ver ().release
10201052
1053+ # Normalize responses on iOS
1054+ if sys .platform == 'ios' :
1055+ system , release , _ , _ = ios_ver ()
1056+
10211057 vals = system , node , release , version , machine
10221058 # Replace 'unknown' values with the more portable ''
10231059 _uname_cache = uname_result (* map (_unknown_as_blank , vals ))
@@ -1297,11 +1333,14 @@ def platform(aliased=False, terse=False):
12971333 system , release , version = system_alias (system , release , version )
12981334
12991335 if system == 'Darwin' :
1300- # macOS (darwin kernel)
1301- macos_release = mac_ver ()[0 ]
1302- if macos_release :
1303- system = 'macOS'
1304- release = macos_release
1336+ # macOS and iOS both report as a "Darwin" kernel
1337+ if sys .platform == "ios" :
1338+ system , release , _ , _ = ios_ver ()
1339+ else :
1340+ macos_release = mac_ver ()[0 ]
1341+ if macos_release :
1342+ system = 'macOS'
1343+ release = macos_release
13051344
13061345 if system == 'Windows' :
13071346 # MS platforms
0 commit comments