(root)/
Python-3.12.0/
Lib/
test/
test_importlib/
test_windows.py
       1  from test.test_importlib import util as test_util
       2  machinery = test_util.import_importlib('importlib.machinery')
       3  
       4  import os
       5  import re
       6  import sys
       7  import unittest
       8  import warnings
       9  from test.support import import_helper
      10  from contextlib import contextmanager
      11  from test.test_importlib.util import temp_module
      12  
      13  import_helper.import_module('winreg', required_on=['win'])
      14  from winreg import (
      15      CreateKey, HKEY_CURRENT_USER,
      16      SetValue, REG_SZ, KEY_ALL_ACCESS,
      17      EnumKey, CloseKey, DeleteKey, OpenKey
      18  )
      19  
      20  def get_platform():
      21      # Port of distutils.util.get_platform().
      22      TARGET_TO_PLAT = {
      23              'x86' : 'win32',
      24              'x64' : 'win-amd64',
      25              'arm' : 'win-arm32',
      26          }
      27      if ('VSCMD_ARG_TGT_ARCH' in os.environ and
      28          os.environ['VSCMD_ARG_TGT_ARCH'] in TARGET_TO_PLAT):
      29          return TARGET_TO_PLAT[os.environ['VSCMD_ARG_TGT_ARCH']]
      30      elif 'amd64' in sys.version.lower():
      31          return 'win-amd64'
      32      elif '(arm)' in sys.version.lower():
      33          return 'win-arm32'
      34      elif '(arm64)' in sys.version.lower():
      35          return 'win-arm64'
      36      else:
      37          return sys.platform
      38  
      39  def delete_registry_tree(root, subkey):
      40      try:
      41          hkey = OpenKey(root, subkey, access=KEY_ALL_ACCESS)
      42      except OSError:
      43          # subkey does not exist
      44          return
      45      while True:
      46          try:
      47              subsubkey = EnumKey(hkey, 0)
      48          except OSError:
      49              # no more subkeys
      50              break
      51          delete_registry_tree(hkey, subsubkey)
      52      CloseKey(hkey)
      53      DeleteKey(root, subkey)
      54  
      55  @contextmanager
      56  def setup_module(machinery, name, path=None):
      57      if machinery.WindowsRegistryFinder.DEBUG_BUILD:
      58          root = machinery.WindowsRegistryFinder.REGISTRY_KEY_DEBUG
      59      else:
      60          root = machinery.WindowsRegistryFinder.REGISTRY_KEY
      61      key = root.format(fullname=name,
      62                        sys_version='%d.%d' % sys.version_info[:2])
      63      base_key = "Software\\Python\\PythonCore\\{}.{}".format(
      64          sys.version_info.major, sys.version_info.minor)
      65      assert key.casefold().startswith(base_key.casefold()), (
      66          "expected key '{}' to start with '{}'".format(key, base_key))
      67      try:
      68          with temp_module(name, "a = 1") as location:
      69              try:
      70                  OpenKey(HKEY_CURRENT_USER, base_key)
      71                  if machinery.WindowsRegistryFinder.DEBUG_BUILD:
      72                      delete_key = os.path.dirname(key)
      73                  else:
      74                      delete_key = key
      75              except OSError:
      76                  delete_key = base_key
      77              subkey = CreateKey(HKEY_CURRENT_USER, key)
      78              if path is None:
      79                  path = location + ".py"
      80              SetValue(subkey, "", REG_SZ, path)
      81              yield
      82      finally:
      83          if delete_key:
      84              delete_registry_tree(HKEY_CURRENT_USER, delete_key)
      85  
      86  
      87  @unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
      88  class ESC[4;38;5;81mWindowsRegistryFinderTests:
      89      # The module name is process-specific, allowing for
      90      # simultaneous runs of the same test on a single machine.
      91      test_module = "spamham{}".format(os.getpid())
      92  
      93      def test_find_spec_missing(self):
      94          spec = self.machinery.WindowsRegistryFinder.find_spec('spam')
      95          self.assertIsNone(spec)
      96  
      97      def test_module_found(self):
      98          with setup_module(self.machinery, self.test_module):
      99              spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
     100              self.assertIsNotNone(spec)
     101  
     102      def test_module_not_found(self):
     103          with setup_module(self.machinery, self.test_module, path="."):
     104              spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
     105              self.assertIsNone(spec)
     106  
     107  (Frozen_WindowsRegistryFinderTests,
     108   Source_WindowsRegistryFinderTests
     109   ) = test_util.test_both(WindowsRegistryFinderTests, machinery=machinery)
     110  
     111  @unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
     112  class ESC[4;38;5;81mWindowsExtensionSuffixTests:
     113      def test_tagged_suffix(self):
     114          suffixes = self.machinery.EXTENSION_SUFFIXES
     115          expected_tag = ".cp{0.major}{0.minor}-{1}.pyd".format(sys.version_info,
     116              re.sub('[^a-zA-Z0-9]', '_', get_platform()))
     117          try:
     118              untagged_i = suffixes.index(".pyd")
     119          except ValueError:
     120              untagged_i = suffixes.index("_d.pyd")
     121              expected_tag = "_d" + expected_tag
     122  
     123          self.assertIn(expected_tag, suffixes)
     124  
     125          # Ensure the tags are in the correct order.
     126          tagged_i = suffixes.index(expected_tag)
     127          self.assertLess(tagged_i, untagged_i)
     128  
     129  (Frozen_WindowsExtensionSuffixTests,
     130   Source_WindowsExtensionSuffixTests
     131   ) = test_util.test_both(WindowsExtensionSuffixTests, machinery=machinery)
     132  
     133  
     134  @unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
     135  class ESC[4;38;5;81mWindowsBootstrapPathTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     136      def check_join(self, expected, *inputs):
     137          from importlib._bootstrap_external import _path_join
     138          actual = _path_join(*inputs)
     139          if expected.casefold() == actual.casefold():
     140              return
     141          self.assertEqual(expected, actual)
     142  
     143      def test_path_join(self):
     144          self.check_join(r"C:\A\B", "C:\\", "A", "B")
     145          self.check_join(r"C:\A\B", "D:\\", "D", "C:\\", "A", "B")
     146          self.check_join(r"C:\A\B", "C:\\", "A", "C:B")
     147          self.check_join(r"C:\A\B", "C:\\", "A\\B")
     148          self.check_join(r"C:\A\B", r"C:\A\B")
     149  
     150          self.check_join("D:A", r"D:", "A")
     151          self.check_join("D:A", r"C:\B\C", "D:", "A")
     152          self.check_join("D:A", r"C:\B\C", r"D:A")
     153  
     154          self.check_join(r"A\B\C", "A", "B", "C")
     155          self.check_join(r"A\B\C", "A", r"B\C")
     156          self.check_join(r"A\B/C", "A", "B/C")
     157          self.check_join(r"A\B\C", "A/", "B\\", "C")
     158  
     159          # Dots are not normalised by this function
     160          self.check_join(r"A\../C", "A", "../C")
     161          self.check_join(r"A.\.\B", "A.", ".", "B")
     162  
     163          self.check_join(r"\\Server\Share\A\B\C", r"\\Server\Share", "A", "B", "C")
     164          self.check_join(r"\\Server\Share\A\B\C", r"\\Server\Share", "D", r"\A", "B", "C")
     165          self.check_join(r"\\Server\Share\A\B\C", r"\\Server2\Share2", "D",
     166                                                   r"\\Server\Share", "A", "B", "C")
     167          self.check_join(r"\\Server\Share\A\B\C", r"\\Server", r"\Share", "A", "B", "C")
     168          self.check_join(r"\\Server\Share", r"\\Server\Share")
     169          self.check_join(r"\\Server\Share\\", r"\\Server\Share\\")
     170  
     171          # Handle edge cases with empty segments
     172          self.check_join("C:\\A", "C:/A", "")
     173          self.check_join("C:\\", "C:/", "")
     174          self.check_join("C:", "C:", "")
     175          self.check_join("//Server/Share\\", "//Server/Share/", "")
     176          self.check_join("//Server/Share\\", "//Server/Share", "")
     177  
     178  if __name__ == '__main__':
     179      unittest.main()