import os
import copy
import pickle
import platform
import subprocess
import sys
import unittest
from unittest import mock

from test import support
from test.support import os_helper

try:
    # Some of the iOS tests need ctypes to operate.
    # Confirm that the ctypes module is available
    # is available.
    import _ctypes
except ImportError:
    _ctypes = None

FEDORA_OS_RELEASE = """\
NAME=Fedora
VERSION="32 (Thirty Two)"
ID=fedora
VERSION_ID=32
VERSION_CODENAME=""
PLATFORM_ID="platform:f32"
PRETTY_NAME="Fedora 32 (Thirty Two)"
ANSI_COLOR="0;34"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:32"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f32/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=32
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=32
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
"""

UBUNTU_OS_RELEASE = """\
NAME="Ubuntu"
VERSION="20.04.1 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.1 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
"""

TEST_OS_RELEASE = r"""
# test data
ID_LIKE="egg spam viking"
EMPTY=
# comments and empty lines are ignored

SINGLE_QUOTE='single'
EMPTY_SINGLE=''
DOUBLE_QUOTE="double"
EMPTY_DOUBLE=""
QUOTES="double\'s"
SPECIALS="\$\`\\\'\""
# invalid lines
=invalid
=
INVALID
IN-VALID=value
IN VALID=value
"""


class PlatformTest(unittest.TestCase):
    def clear_caches(self):
        platform._platform_cache.clear()
        platform._sys_version_cache.clear()
        platform._uname_cache = None
        platform._os_release_cache = None

    def test_architecture(self):
        res = platform.architecture()

    @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())"
            self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))

    def test_platform(self):
        for aliased in (False, True):
            for terse in (False, True):
                res = platform.platform(aliased, terse)

    def test_system(self):
        res = platform.system()

    def test_node(self):
        res = platform.node()

    def test_release(self):
        res = platform.release()

    def test_version(self):
        res = platform.version()

    def test_machine(self):
        res = platform.machine()

    def test_processor(self):
        res = platform.processor()

    def setUp(self):
        self.save_version = sys.version
        self.save_git = sys._git
        self.save_platform = sys.platform

    def tearDown(self):
        sys.version = self.save_version
        sys._git = self.save_git
        sys.platform = self.save_platform

    def test_sys_version(self):
        # Old test.
        for input, output in (
            ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]',
             ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')),
            ('2.4.3 (truncation, date, t) \n[GCC]',
             ('CPython', '2.4.3', '', '', 'truncation', 'date t', 'GCC')),
            ('2.4.3 (truncation, date, ) \n[GCC]',
             ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
            ('2.4.3 (truncation, date,) \n[GCC]',
             ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
            ('2.4.3 (truncation, date) \n[GCC]',
             ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
            ('2.4.3 (truncation, d) \n[GCC]',
             ('CPython', '2.4.3', '', '', 'truncation', 'd', 'GCC')),
            ('2.4.3 (truncation, ) \n[GCC]',
             ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
            ('2.4.3 (truncation,) \n[GCC]',
             ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
            ('2.4.3 (truncation) \n[GCC]',
             ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
            ):
            # branch and revision are not "parsed", but fetched
            # from sys._git.  Ignore them
            (name, version, branch, revision, buildno, builddate, compiler) \
                   = platform._sys_version(input)
            self.assertEqual(
                (name, version, '', '', buildno, builddate, compiler), output)

        # Tests for python_implementation(), python_version(), python_branch(),
        # python_revision(), python_build(), and python_compiler().
        sys_versions = {
            ("2.6.1 (r261:67515, Dec  6 2008, 15:26:00) \n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]",
             ('CPython', 'tags/r261', '67515'), self.save_platform)
            :
                ("CPython", "2.6.1", "tags/r261", "67515",
                 ('r261:67515', 'Dec  6 2008 15:26:00'),
                 'GCC 4.0.1 (Apple Computer, Inc. build 5370)'),

            ("3.10.8 (tags/v3.10.8:aaaf517424, Feb 14 2023, 16:28:12) [GCC 9.4.0]",
             None, "linux")
            :
                ('CPython', '3.10.8', '', '',
                ('tags/v3.10.8:aaaf517424', 'Feb 14 2023 16:28:12'), 'GCC 9.4.0'),

            ("2.5 (trunk:6107, Mar 26 2009, 13:02:18) \n[Java HotSpot(TM) Client VM (\"Apple Computer, Inc.\")]",
            ('Jython', 'trunk', '6107'), "java1.5.0_16")
            :
                ("Jython", "2.5.0", "trunk", "6107",
                 ('trunk:6107', 'Mar 26 2009'), "java1.5.0_16"),

            ("2.5.2 (63378, Mar 26 2009, 18:03:29)\n[PyPy 1.0.0]",
             ('PyPy', 'trunk', '63378'), self.save_platform)
            :
                ("PyPy", "2.5.2", "trunk", "63378", ('63378', 'Mar 26 2009'),
                 "")
            }
        for (version_tag, scm, sys_platform), info in \
                sys_versions.items():
            sys.version = version_tag
            if scm is None:
                if hasattr(sys, "_git"):
                    del sys._git
            else:
                sys._git = scm
            if sys_platform is not None:
                sys.platform = sys_platform
            self.assertEqual(platform.python_implementation(), info[0])
            self.assertEqual(platform.python_version(), info[1])
            self.assertEqual(platform.python_branch(), info[2])
            self.assertEqual(platform.python_revision(), info[3])
            self.assertEqual(platform.python_build(), info[4])
            self.assertEqual(platform.python_compiler(), info[5])

        with self.assertRaises(ValueError):
            platform._sys_version('2. 4.3 (truncation) \n[GCC]')

    def test_system_alias(self):
        res = platform.system_alias(
            platform.system(),
            platform.release(),
            platform.version(),
        )

    def test_uname(self):
        res = platform.uname()
        self.assertTrue(any(res))
        self.assertEqual(res[0], res.system)
        self.assertEqual(res[-6], res.system)
        self.assertEqual(res[1], res.node)
        self.assertEqual(res[-5], res.node)
        self.assertEqual(res[2], res.release)
        self.assertEqual(res[-4], res.release)
        self.assertEqual(res[3], res.version)
        self.assertEqual(res[-3], res.version)
        self.assertEqual(res[4], res.machine)
        self.assertEqual(res[-2], res.machine)
        self.assertEqual(res[5], res.processor)
        self.assertEqual(res[-1], res.processor)
        self.assertEqual(len(res), 6)

        if os.name == "posix":
            uname = os.uname()
            self.assertEqual(res.node, uname.nodename)
            self.assertEqual(res.version, uname.version)
            self.assertEqual(res.machine, uname.machine)

            if sys.platform == "android":
                self.assertEqual(res.system, "Android")
                self.assertEqual(res.release, platform.android_ver().release)
            elif sys.platform == "ios":
                # Platform module needs ctypes for full operation. If ctypes
                # isn't available, there's no ObjC module, and dummy values are
                # returned.
                if _ctypes:
                    self.assertIn(res.system, {"iOS", "iPadOS"})
                    self.assertEqual(res.release, platform.ios_ver().release)
                else:
                    self.assertEqual(res.system, "")
                    self.assertEqual(res.release, "")
            else:
                self.assertEqual(res.system, uname.sysname)
                self.assertEqual(res.release, uname.release)


    @unittest.skipUnless(sys.platform.startswith('win'), "windows only test")
    def test_uname_win32_without_wmi(self):
        def raises_oserror(*a):
            raise OSError()

        with support.swap_attr(platform, '_wmi_query', raises_oserror):
            self.test_uname()

    def test_uname_cast_to_tuple(self):
        res = platform.uname()
        expected = (
            res.system, res.node, res.release, res.version, res.machine,
            res.processor,
        )
        self.assertEqual(tuple(res), expected)

    def test_uname_replace(self):
        res = platform.uname()
        new = res._replace(
            system='system', node='node', release='release',
            version='version', machine='machine')
        self.assertEqual(new.system, 'system')
        self.assertEqual(new.node, 'node')
        self.assertEqual(new.release, 'release')
        self.assertEqual(new.version, 'version')
        self.assertEqual(new.machine, 'machine')
        # processor cannot be replaced
        self.assertEqual(new.processor, res.processor)

    def test_uname_copy(self):
        uname = platform.uname()
        self.assertEqual(copy.copy(uname), uname)
        self.assertEqual(copy.deepcopy(uname), uname)

    def test_uname_pickle(self):
        orig = platform.uname()
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            with self.subTest(protocol=proto):
                pickled = pickle.dumps(orig, proto)
                restored = pickle.loads(pickled)
                self.assertEqual(restored, orig)

    def test_uname_slices(self):
        res = platform.uname()
        expected = tuple(res)
        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
        of 'uname -p'. See Issue 35967 for rationale.
        """
        try:
            proc_res = subprocess.check_output(['uname', '-p'], text=True).strip()
            expect = platform._unknown_as_blank(proc_res)
        except (OSError, subprocess.CalledProcessError):
            expect = ''
        self.assertEqual(platform.uname().processor, expect)

    @unittest.skipUnless(sys.platform.startswith('win'), "windows only test")
    def test_uname_win32_ARCHITEW6432(self):
        # Issue 7860: make sure we get architecture from the correct variable
        # on 64 bit Windows: if PROCESSOR_ARCHITEW6432 exists we should be
        # using it, per
        # http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx

        # We also need to suppress WMI checks, as those are reliable and
        # overrule the environment variables
        def raises_oserror(*a):
            raise OSError()

        with support.swap_attr(platform, '_wmi_query', raises_oserror):
            with os_helper.EnvironmentVarGuard() as environ:
                try:
                    if 'PROCESSOR_ARCHITEW6432' in environ:
                        del environ['PROCESSOR_ARCHITEW6432']
                    environ['PROCESSOR_ARCHITECTURE'] = 'foo'
                    platform._uname_cache = None
                    system, node, release, version, machine, processor = platform.uname()
                    self.assertEqual(machine, 'foo')
                    environ['PROCESSOR_ARCHITEW6432'] = 'bar'
                    platform._uname_cache = None
                    system, node, release, version, machine, processor = platform.uname()
                    self.assertEqual(machine, 'bar')
                finally:
                    platform._uname_cache = None

    def test_java_ver(self):
        import re
        msg = re.escape(
            "'java_ver' is deprecated and slated for removal in Python 3.15"
        )
        with self.assertWarnsRegex(DeprecationWarning, msg):
            res = platform.java_ver()
        self.assertEqual(len(res), 4)

    @unittest.skipUnless(support.MS_WINDOWS, 'This test only makes sense on Windows')
    def test_win32_ver(self):
        release1, version1, csd1, ptype1 = 'a', 'b', 'c', 'd'
        res = platform.win32_ver(release1, version1, csd1, ptype1)
        self.assertEqual(len(res), 4)
        release, version, csd, ptype = res
        if release:
            # Currently, release names always come from internal dicts,
            # but this could change over time. For now, we just check that
            # release is something different from what we have passed.
            self.assertNotEqual(release, release1)
        if version:
            # It is rather hard to test explicit version without
            # going deep into the details.
            self.assertIn('.', version)
            for v in version.split('.'):
                int(v)  # should not fail
        if csd:
            self.assertTrue(csd.startswith('SP'), msg=csd)
        if ptype:
            if os.cpu_count() > 1:
                self.assertIn('Multiprocessor', ptype)
            else:
                self.assertIn('Uniprocessor', ptype)

    @unittest.skipIf(support.MS_WINDOWS, 'This test only makes sense on non Windows')
    def test_win32_ver_on_non_windows(self):
        release, version, csd, ptype = 'a', '1.0', 'c', 'd'
        res = platform.win32_ver(release, version, csd, ptype)
        self.assertSequenceEqual(res, (release, version, csd, ptype), seq_type=tuple)

    def test_mac_ver(self):
        res = platform.mac_ver()

        if platform.uname().system == 'Darwin':
            # We are on a macOS system, check that the right version
            # information is returned
            output = subprocess.check_output(['sw_vers'], text=True)
            for line in output.splitlines():
                if line.startswith('ProductVersion:'):
                    real_ver = line.strip().split()[-1]
                    break
            else:
                self.fail(f"failed to parse sw_vers output: {output!r}")

            result_list = res[0].split('.')
            expect_list = real_ver.split('.')
            len_diff = len(result_list) - len(expect_list)
            # On Snow Leopard, sw_vers reports 10.6.0 as 10.6
            if len_diff > 0:
                expect_list.extend(['0'] * len_diff)
            # For compatibility with older binaries, macOS 11.x may report
            # itself as '10.16' rather than '11.x.y'.
            if result_list != ['10', '16']:
                self.assertEqual(result_list, expect_list)

            # res[1] claims to contain
            # (version, dev_stage, non_release_version)
            # That information is no longer available
            self.assertEqual(res[1], ('', '', ''))

            if sys.byteorder == 'little':
                self.assertIn(res[2], ('i386', 'x86_64', 'arm64'))
            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
        #
        # This test checks that the fix for that issue works.
        #
        pid = os.fork()
        if pid == 0:
            # child
            info = platform.mac_ver()
            os._exit(0)

        else:
            # parent
            support.wait_process(pid, exitcode=0)

    def test_ios_ver(self):
        result = platform.ios_ver()

        # ios_ver is only fully available on iOS where ctypes is available.
        if sys.platform == "ios" and _ctypes:
            system, release, model, is_simulator = result
            # Result is a namedtuple
            self.assertEqual(result.system, system)
            self.assertEqual(result.release, release)
            self.assertEqual(result.model, model)
            self.assertEqual(result.is_simulator, is_simulator)

            # We can't assert specific values without reproducing the logic of
            # ios_ver(), so we check that the values are broadly what we expect.

            # System is either iOS or iPadOS, depending on the test device
            self.assertIn(system, {"iOS", "iPadOS"})

            # Release is a numeric version specifier with at least 2 parts
            parts = release.split(".")
            self.assertGreaterEqual(len(parts), 2)
            self.assertTrue(all(part.isdigit() for part in parts))

            # If this is a simulator, we get a high level device descriptor
            # with no identifying model number. If this is a physical device,
            # we get a model descriptor like "iPhone13,1"
            if is_simulator:
                self.assertIn(model, {"iPhone", "iPad"})
            else:
                self.assertTrue(
                    (model.startswith("iPhone") or model.startswith("iPad"))
                    and "," in model
                )

            self.assertEqual(type(is_simulator), bool)
        else:
            # On non-iOS platforms, calling ios_ver doesn't fail; you get
            # default values
            self.assertEqual(result.system, "")
            self.assertEqual(result.release, "")
            self.assertEqual(result.model, "")
            self.assertFalse(result.is_simulator)

            # Check the fallback values can be overridden by arguments
            override = platform.ios_ver("Foo", "Bar", "Whiz", True)
            self.assertEqual(override.system, "Foo")
            self.assertEqual(override.release, "Bar")
            self.assertEqual(override.model, "Whiz")
            self.assertTrue(override.is_simulator)

    @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 \
           os.path.exists(sys.executable+'.exe'):
            # Cygwin horror
            executable = sys.executable + '.exe'
        elif sys.platform == "win32" and not os.path.exists(sys.executable):
            # App symlink appears to not exist, but we want the
            # real executable here anyway
            import _winapi
            executable = _winapi.GetModuleFileName(0)
        else:
            executable = sys.executable
        platform.libc_ver(executable)

        filename = os_helper.TESTFN
        self.addCleanup(os_helper.unlink, filename)

        with mock.patch('os.confstr', create=True, return_value='mock 1.0'):
            # test os.confstr() code path
            self.assertEqual(platform.libc_ver(), ('mock', '1.0'))

            # test the different regular expressions
            for data, expected in (
                (b'__libc_init', ('libc', '')),
                (b'GLIBC_2.9', ('glibc', '2.9')),
                (b'libc.so.1.2.5', ('libc', '1.2.5')),
                (b'libc_pthread.so.1.2.5', ('libc', '1.2.5_pthread')),
                (b'', ('', '')),
            ):
                with open(filename, 'wb') as fp:
                    fp.write(b'[xxx%sxxx]' % data)
                    fp.flush()

                # os.confstr() must not be used if executable is set
                self.assertEqual(platform.libc_ver(executable=filename),
                                 expected)

        # binary containing multiple versions: get the most recent,
        # make sure that 1.9 is seen as older than 1.23.4
        chunksize = 16384
        with open(filename, 'wb') as f:
            # test match at chunk boundary
            f.write(b'x'*(chunksize - 10))
            f.write(b'GLIBC_1.23.4\0GLIBC_1.9\0GLIBC_1.21\0')
        self.assertEqual(platform.libc_ver(filename, chunksize=chunksize),
                         ('glibc', '1.23.4'))

    def test_android_ver(self):
        res = platform.android_ver()
        self.assertIsInstance(res, tuple)
        self.assertEqual(res, (res.release, res.api_level, res.manufacturer,
                               res.model, res.device, res.is_emulator))

        if sys.platform == "android":
            for name in ["release", "manufacturer", "model", "device"]:
                with self.subTest(name):
                    value = getattr(res, name)
                    self.assertIsInstance(value, str)
                    self.assertNotEqual(value, "")

            self.assertIsInstance(res.api_level, int)
            self.assertGreaterEqual(res.api_level, sys.getandroidapilevel())

            self.assertIsInstance(res.is_emulator, bool)

        # When not running on Android, it should return the default values.
        else:
            self.assertEqual(res.release, "")
            self.assertEqual(res.api_level, 0)
            self.assertEqual(res.manufacturer, "")
            self.assertEqual(res.model, "")
            self.assertEqual(res.device, "")
            self.assertEqual(res.is_emulator, False)

            # Default values may also be overridden using parameters.
            res = platform.android_ver(
                "alpha", 1, "bravo", "charlie", "delta", True)
            self.assertEqual(res.release, "alpha")
            self.assertEqual(res.api_level, 1)
            self.assertEqual(res.manufacturer, "bravo")
            self.assertEqual(res.model, "charlie")
            self.assertEqual(res.device, "delta")
            self.assertEqual(res.is_emulator, True)

    @support.cpython_only
    def test__comparable_version(self):
        from platform import _comparable_version as V
        self.assertEqual(V('1.2.3'), V('1.2.3'))
        self.assertLess(V('1.2.3'), V('1.2.10'))
        self.assertEqual(V('1.2.3.4'), V('1_2-3+4'))
        self.assertLess(V('1.2spam'), V('1.2dev'))
        self.assertLess(V('1.2dev'), V('1.2alpha'))
        self.assertLess(V('1.2dev'), V('1.2a'))
        self.assertLess(V('1.2alpha'), V('1.2beta'))
        self.assertLess(V('1.2a'), V('1.2b'))
        self.assertLess(V('1.2beta'), V('1.2c'))
        self.assertLess(V('1.2b'), V('1.2c'))
        self.assertLess(V('1.2c'), V('1.2RC'))
        self.assertLess(V('1.2c'), V('1.2rc'))
        self.assertLess(V('1.2RC'), V('1.2.0'))
        self.assertLess(V('1.2rc'), V('1.2.0'))
        self.assertLess(V('1.2.0'), V('1.2pl'))
        self.assertLess(V('1.2.0'), V('1.2p'))

        self.assertLess(V('1.5.1'), V('1.5.2b2'))
        self.assertLess(V('3.10a'), V('161'))
        self.assertEqual(V('8.02'), V('8.02'))
        self.assertLess(V('3.4j'), V('1996.07.12'))
        self.assertLess(V('3.1.1.6'), V('3.2.pl0'))
        self.assertLess(V('2g6'), V('11g'))
        self.assertLess(V('0.9'), V('2.2'))
        self.assertLess(V('1.2'), V('1.2.1'))
        self.assertLess(V('1.1'), V('1.2.2'))
        self.assertLess(V('1.1'), V('1.2'))
        self.assertLess(V('1.2.1'), V('1.2.2'))
        self.assertLess(V('1.2'), V('1.2.2'))
        self.assertLess(V('0.4'), V('0.4.0'))
        self.assertLess(V('1.13++'), V('5.5.kw'))
        self.assertLess(V('0.960923'), V('2.2beta29'))


    def test_macos(self):
        self.addCleanup(self.clear_caches)

        uname = ('Darwin', 'hostname', '17.7.0',
                 ('Darwin Kernel Version 17.7.0: '
                  'Thu Jun 21 22:53:14 PDT 2018; '
                  'root:xnu-4570.71.2~1/RELEASE_X86_64'),
                 'x86_64', 'i386')
        arch = ('64bit', '')
        with mock.patch.object(sys, "platform", "darwin"), \
             mock.patch.object(platform, 'uname', return_value=uname), \
             mock.patch.object(platform, 'architecture', return_value=arch):
            for mac_ver, expected_terse, expected in [
                # darwin: mac_ver() returns empty strings
                (('', '', ''),
                 'Darwin-17.7.0',
                 'Darwin-17.7.0-x86_64-i386-64bit'),
                # macOS: mac_ver() returns macOS version
                (('10.13.6', ('', '', ''), 'x86_64'),
                 'macOS-10.13.6',
                 'macOS-10.13.6-x86_64-i386-64bit'),
            ]:
                with mock.patch.object(platform, 'mac_ver',
                                       return_value=mac_ver):
                    self.clear_caches()
                    self.assertEqual(platform.platform(terse=1), expected_terse)
                    self.assertEqual(platform.platform(), expected)

    def test_freedesktop_os_release(self):
        self.addCleanup(self.clear_caches)
        self.clear_caches()

        if any(os.path.isfile(fn) for fn in platform._os_release_candidates):
            info = platform.freedesktop_os_release()
            self.assertIn("NAME", info)
            self.assertIn("ID", info)

            info["CPYTHON_TEST"] = "test"
            self.assertNotIn(
                "CPYTHON_TEST",
                platform.freedesktop_os_release()
            )
        else:
            with self.assertRaises(OSError):
                platform.freedesktop_os_release()

    def test_parse_os_release(self):
        info = platform._parse_os_release(FEDORA_OS_RELEASE.splitlines())
        self.assertEqual(info["NAME"], "Fedora")
        self.assertEqual(info["ID"], "fedora")
        self.assertNotIn("ID_LIKE", info)
        self.assertEqual(info["VERSION_CODENAME"], "")

        info = platform._parse_os_release(UBUNTU_OS_RELEASE.splitlines())
        self.assertEqual(info["NAME"], "Ubuntu")
        self.assertEqual(info["ID"], "ubuntu")
        self.assertEqual(info["ID_LIKE"], "debian")
        self.assertEqual(info["VERSION_CODENAME"], "focal")

        info = platform._parse_os_release(TEST_OS_RELEASE.splitlines())
        expected = {
            "ID": "linux",
            "NAME": "Linux",
            "PRETTY_NAME": "Linux",
            "ID_LIKE": "egg spam viking",
            "EMPTY": "",
            "DOUBLE_QUOTE": "double",
            "EMPTY_DOUBLE": "",
            "SINGLE_QUOTE": "single",
            "EMPTY_SINGLE": "",
            "QUOTES": "double's",
            "SPECIALS": "$`\\'\"",
        }
        self.assertEqual(info, expected)
        self.assertEqual(len(info["SPECIALS"]), 5)


if __name__ == '__main__':
    unittest.main()
