python (3.12.0)
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()