diff --git a/Lib/platform.py b/Lib/platform.py index fe88fa9d5..58b66078e 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -5,7 +5,7 @@ If called from the command line, it prints the platform information concatenated as single string to stdout. The output - format is useable as part of a filename. + format is usable as part of a filename. """ # This module is maintained by Marc-Andre Lemburg . @@ -116,7 +116,6 @@ import collections import os import re import sys -import subprocess import functools import itertools @@ -169,7 +168,7 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): Note that the function has intimate knowledge of how different libc versions add symbols to the executable and thus is probably - only useable for executables compiled using gcc. + only usable for executables compiled using gcc. The file is read and scanned in chunks of chunksize bytes. @@ -187,12 +186,15 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): executable = sys.executable + if not executable: + # sys.executable is not set. + return lib, version + V = _comparable_version - if hasattr(os.path, 'realpath'): - # Python 2.2 introduced os.path.realpath(); it is used - # here to work around problems with Cygwin not being - # able to open symlinks for reading - executable = os.path.realpath(executable) + # We use os.path.realpath() + # here to work around problems with Cygwin not being + # able to open symlinks for reading + executable = os.path.realpath(executable) with open(executable, 'rb') as f: binary = f.read(chunksize) pos = 0 @@ -283,6 +285,7 @@ def _syscmd_ver(system='', release='', version='', stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL, text=True, + encoding="locale", shell=True) except (OSError, subprocess.CalledProcessError) as why: #print('Command %s failed: %s' % (cmd, why)) @@ -609,7 +612,10 @@ def _syscmd_file(target, default=''): # XXX Others too ? return default - import subprocess + try: + import subprocess + except ImportError: + return default target = _follow_symlinks(target) # "file" output is locale dependent: force the usage of the C locale # to get deterministic behavior. @@ -748,11 +754,16 @@ class _Processor: """ Fall back to `uname -p` """ + try: + import subprocess + except ImportError: + return None try: return subprocess.check_output( ['uname', '-p'], stderr=subprocess.DEVNULL, text=True, + encoding="utf8", ).strip() except (OSError, subprocess.CalledProcessError): pass @@ -776,6 +787,8 @@ class uname_result( except when needed. """ + _fields = ('system', 'node', 'release', 'version', 'machine', 'processor') + @functools.cached_property def processor(self): return _unknown_as_blank(_Processor.get()) @@ -789,7 +802,7 @@ class uname_result( @classmethod def _make(cls, iterable): # override factory to affect length check - num_fields = len(cls._fields) + num_fields = len(cls._fields) - 1 result = cls.__new__(cls, *iterable) if len(result) != num_fields + 1: msg = f'Expected {num_fields} arguments, got {len(result)}' @@ -803,7 +816,7 @@ class uname_result( return len(tuple(iter(self))) def __reduce__(self): - return uname_result, tuple(self)[:len(self._fields)] + return uname_result, tuple(self)[:len(self._fields) - 1] _uname_cache = None diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index c6a1cc341..c9f27575b 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -78,8 +78,8 @@ class PlatformTest(unittest.TestCase): def test_architecture(self): res = platform.architecture() - @unittest.expectedFailureIfWindows("TODO: RUSTPYTHON") @os_helper.skip_unless_symlink + @support.requires_subprocess() def test_architecture_via_symlink(self): # issue3762 with support.PythonSymlink() as py: cmd = "-c", "import platform; print(platform.architecture())" @@ -269,7 +269,16 @@ class PlatformTest(unittest.TestCase): self.assertEqual(res[:], expected) self.assertEqual(res[:5], expected[:5]) + def test_uname_fields(self): + self.assertIn('processor', platform.uname()._fields) + + def test_uname_asdict(self): + res = platform.uname()._asdict() + self.assertEqual(len(res), 6) + self.assertIn('processor', res) + @unittest.skipIf(sys.platform in ['win32', 'OpenVMS'], "uname -p not used") + @support.requires_subprocess() def test_uname_processor(self): """ On some systems, the processor must match the output @@ -346,6 +355,7 @@ class PlatformTest(unittest.TestCase): else: self.assertEqual(res[2], 'PowerPC') + @unittest.skipUnless(sys.platform == 'darwin', "OSX only test") def test_mac_ver_with_fork(self): # Issue7895: platform.mac_ver() crashes when using fork without exec @@ -362,6 +372,7 @@ class PlatformTest(unittest.TestCase): # parent support.wait_process(pid, exitcode=0) + @unittest.skipIf(support.is_emscripten, "Does not apply to Emscripten") def test_libc_ver(self): # check that libc_ver(executable) doesn't raise an exception if os.path.isdir(sys.executable) and \ diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 2d662f94a..6db144298 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -346,7 +346,6 @@ class TestSysConfig(unittest.TestCase): wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) - @unittest.expectedFailureIfWindows("TODO: RUSTPYTHON") @skip_unless_symlink @requires_subprocess() def test_symlink(self): # Issue 7880 diff --git a/vm/src/stdlib/sys.rs b/vm/src/stdlib/sys.rs index 47f9376f1..81498a7b0 100644 --- a/vm/src/stdlib/sys.rs +++ b/vm/src/stdlib/sys.rs @@ -71,10 +71,15 @@ mod sys { const PS1: &str = ">>>>> "; #[pyattr(name = "ps2")] const PS2: &str = "..... "; + #[cfg(windows)] #[pyattr(name = "_vpath")] const VPATH: Option<&'static str> = None; // TODO: actual VPATH value + #[cfg(windows)] + #[pyattr(name = "dllhandle")] + const DLLHANDLE: usize = 0; + #[pyattr] fn default_prefix(_vm: &VirtualMachine) -> &'static str { // TODO: the windows one doesn't really make sense