(root)/
Python-3.11.7/
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.assertIs(spec, None)
      96  
      97      def test_find_module_missing(self):
      98          with warnings.catch_warnings():
      99              warnings.simplefilter("ignore", DeprecationWarning)
     100              loader = self.machinery.WindowsRegistryFinder.find_module('spam')
     101          self.assertIs(loader, None)
     102  
     103      def test_module_found(self):
     104          with setup_module(self.machinery, self.test_module):
     105              with warnings.catch_warnings():
     106                  warnings.simplefilter("ignore", DeprecationWarning)
     107                  loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module)
     108              spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
     109              self.assertIsNot(loader, None)
     110              self.assertIsNot(spec, None)
     111  
     112      def test_module_not_found(self):
     113          with setup_module(self.machinery, self.test_module, path="."):
     114              with warnings.catch_warnings():
     115                  warnings.simplefilter("ignore", DeprecationWarning)
     116                  loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module)
     117              spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
     118              self.assertIsNone(loader)
     119              self.assertIsNone(spec)
     120  
     121  (Frozen_WindowsRegistryFinderTests,
     122   Source_WindowsRegistryFinderTests
     123   ) = test_util.test_both(WindowsRegistryFinderTests, machinery=machinery)
     124  
     125  @unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
     126  class ESC[4;38;5;81mWindowsExtensionSuffixTests:
     127      def test_tagged_suffix(self):
     128          suffixes = self.machinery.EXTENSION_SUFFIXES
     129          expected_tag = ".cp{0.major}{0.minor}-{1}.pyd".format(sys.version_info,
     130              re.sub('[^a-zA-Z0-9]', '_', get_platform()))
     131          try:
     132              untagged_i = suffixes.index(".pyd")
     133          except ValueError:
     134              untagged_i = suffixes.index("_d.pyd")
     135              expected_tag = "_d" + expected_tag
     136  
     137          self.assertIn(expected_tag, suffixes)
     138  
     139          # Ensure the tags are in the correct order.
     140          tagged_i = suffixes.index(expected_tag)
     141          self.assertLess(tagged_i, untagged_i)
     142  
     143  (Frozen_WindowsExtensionSuffixTests,
     144   Source_WindowsExtensionSuffixTests
     145   ) = test_util.test_both(WindowsExtensionSuffixTests, machinery=machinery)
     146  
     147  
     148  @unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
     149  class ESC[4;38;5;81mWindowsBootstrapPathTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     150      def check_join(self, expected, *inputs):
     151          from importlib._bootstrap_external import _path_join
     152          actual = _path_join(*inputs)
     153          if expected.casefold() == actual.casefold():
     154              return
     155          self.assertEqual(expected, actual)
     156  
     157      def test_path_join(self):
     158          self.check_join(r"C:\A\B", "C:\\", "A", "B")
     159          self.check_join(r"C:\A\B", "D:\\", "D", "C:\\", "A", "B")
     160          self.check_join(r"C:\A\B", "C:\\", "A", "C:B")
     161          self.check_join(r"C:\A\B", "C:\\", "A\\B")
     162          self.check_join(r"C:\A\B", r"C:\A\B")
     163  
     164          self.check_join("D:A", r"D:", "A")
     165          self.check_join("D:A", r"C:\B\C", "D:", "A")
     166          self.check_join("D:A", r"C:\B\C", r"D:A")
     167  
     168          self.check_join(r"A\B\C", "A", "B", "C")
     169          self.check_join(r"A\B\C", "A", r"B\C")
     170          self.check_join(r"A\B/C", "A", "B/C")
     171          self.check_join(r"A\B\C", "A/", "B\\", "C")
     172  
     173          # Dots are not normalised by this function
     174          self.check_join(r"A\../C", "A", "../C")
     175          self.check_join(r"A.\.\B", "A.", ".", "B")
     176  
     177          self.check_join(r"\\Server\Share\A\B\C", r"\\Server\Share", "A", "B", "C")
     178          self.check_join(r"\\Server\Share\A\B\C", r"\\Server\Share", "D", r"\A", "B", "C")
     179          self.check_join(r"\\Server\Share\A\B\C", r"\\Server2\Share2", "D",
     180                                                   r"\\Server\Share", "A", "B", "C")
     181          self.check_join(r"\\Server\Share\A\B\C", r"\\Server", r"\Share", "A", "B", "C")
     182          self.check_join(r"\\Server\Share", r"\\Server\Share")
     183          self.check_join(r"\\Server\Share\\", r"\\Server\Share\\")
     184  
     185          # Handle edge cases with empty segments
     186          self.check_join("C:\\A", "C:/A", "")
     187          self.check_join("C:\\", "C:/", "")
     188          self.check_join("C:", "C:", "")
     189          self.check_join("//Server/Share\\", "//Server/Share/", "")
     190          self.check_join("//Server/Share\\", "//Server/Share", "")
     191  
     192  if __name__ == '__main__':
     193      unittest.main()