py2docfx 0.1.11rc1981066__py3-none-any.whl → 0.1.11rc1997820__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. py2docfx/__main__.py +24 -15
  2. py2docfx/convert_prepare/environment.py +13 -10
  3. py2docfx/convert_prepare/generate_document.py +6 -6
  4. py2docfx/convert_prepare/get_source.py +7 -7
  5. py2docfx/convert_prepare/git.py +10 -13
  6. py2docfx/convert_prepare/install_package.py +2 -2
  7. py2docfx/convert_prepare/pack.py +7 -10
  8. py2docfx/convert_prepare/package_info.py +3 -3
  9. py2docfx/convert_prepare/pip_utils.py +12 -14
  10. py2docfx/convert_prepare/post_process/merge_toc.py +3 -2
  11. py2docfx/convert_prepare/sphinx_caller.py +34 -12
  12. py2docfx/convert_prepare/tests/test_environment.py +0 -3
  13. py2docfx/convert_prepare/tests/test_generate_document.py +4 -2
  14. py2docfx/convert_prepare/tests/test_get_source.py +22 -14
  15. py2docfx/convert_prepare/tests/test_pack.py +6 -3
  16. py2docfx/convert_prepare/tests/test_params.py +0 -1
  17. py2docfx/convert_prepare/tests/test_sphinx_caller.py +10 -8
  18. py2docfx/convert_prepare/tests/test_subpackage.py +1 -0
  19. py2docfx/docfx_yaml/build_finished.py +1 -1
  20. py2docfx/docfx_yaml/logger.py +56 -55
  21. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/authorization_code.py +1 -1
  22. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/azd_cli.py +20 -14
  23. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/azure_arc.py +1 -1
  24. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/azure_cli.py +36 -14
  25. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/azure_powershell.py +1 -1
  26. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/chained.py +2 -2
  27. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/default.py +4 -3
  28. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/imds.py +2 -2
  29. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/managed_identity.py +1 -1
  30. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/__init__.py +2 -0
  31. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/auth_code_redirect_handler.py +1 -1
  32. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/decorators.py +15 -7
  33. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/interactive.py +1 -1
  34. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/managed_identity_client.py +0 -1
  35. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/msal_client.py +1 -1
  36. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/msal_managed_identity_client.py +2 -1
  37. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/shared_token_cache.py +3 -3
  38. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/utils.py +17 -2
  39. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_version.py +1 -1
  40. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/azd_cli.py +14 -11
  41. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/azure_cli.py +30 -12
  42. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/default.py +2 -2
  43. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/imds.py +3 -3
  44. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/managed_identity.py +1 -1
  45. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_internal/decorators.py +15 -7
  46. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_internal/managed_identity_client.py +1 -1
  47. py2docfx/venv/venv1/Lib/site-packages/cryptography/__about__.py +1 -1
  48. py2docfx/venv/venv1/Lib/site-packages/google/api/annotations_pb2.py +7 -4
  49. py2docfx/venv/venv1/Lib/site-packages/google/api/auth_pb2.py +6 -3
  50. py2docfx/venv/venv1/Lib/site-packages/google/api/backend_pb2.py +14 -7
  51. py2docfx/venv/venv1/Lib/site-packages/google/api/billing_pb2.py +6 -3
  52. py2docfx/venv/venv1/Lib/site-packages/google/api/client_pb2.py +47 -38
  53. py2docfx/venv/venv1/Lib/site-packages/google/api/config_change_pb2.py +6 -3
  54. py2docfx/venv/venv1/Lib/site-packages/google/api/consumer_pb2.py +6 -3
  55. py2docfx/venv/venv1/Lib/site-packages/google/api/context_pb2.py +6 -3
  56. py2docfx/venv/venv1/Lib/site-packages/google/api/control_pb2.py +6 -4
  57. py2docfx/venv/venv1/Lib/site-packages/google/api/distribution_pb2.py +7 -5
  58. py2docfx/venv/venv1/Lib/site-packages/google/api/documentation_pb2.py +6 -3
  59. py2docfx/venv/venv1/Lib/site-packages/google/api/endpoint_pb2.py +6 -3
  60. py2docfx/venv/venv1/Lib/site-packages/google/api/error_reason_pb2.py +6 -3
  61. py2docfx/venv/venv1/Lib/site-packages/google/api/field_behavior_pb2.py +8 -6
  62. py2docfx/venv/venv1/Lib/site-packages/google/api/field_info_pb2.py +6 -4
  63. py2docfx/venv/venv1/Lib/site-packages/google/api/http_pb2.py +7 -4
  64. py2docfx/venv/venv1/Lib/site-packages/google/api/httpbody_pb2.py +6 -4
  65. py2docfx/venv/venv1/Lib/site-packages/google/api/label_pb2.py +7 -4
  66. py2docfx/venv/venv1/Lib/site-packages/google/api/launch_stage_pb2.py +6 -3
  67. py2docfx/venv/venv1/Lib/site-packages/google/api/log_pb2.py +6 -4
  68. py2docfx/venv/venv1/Lib/site-packages/google/api/logging_pb2.py +6 -3
  69. py2docfx/venv/venv1/Lib/site-packages/google/api/metric_pb2.py +12 -9
  70. py2docfx/venv/venv1/Lib/site-packages/google/api/monitored_resource_pb2.py +15 -10
  71. py2docfx/venv/venv1/Lib/site-packages/google/api/monitoring_pb2.py +6 -3
  72. py2docfx/venv/venv1/Lib/site-packages/google/api/policy_pb2.py +7 -5
  73. py2docfx/venv/venv1/Lib/site-packages/google/api/quota_pb2.py +10 -7
  74. py2docfx/venv/venv1/Lib/site-packages/google/api/resource_pb2.py +7 -5
  75. py2docfx/venv/venv1/Lib/site-packages/google/api/routing_pb2.py +6 -4
  76. py2docfx/venv/venv1/Lib/site-packages/google/api/service_pb2.py +15 -12
  77. py2docfx/venv/venv1/Lib/site-packages/google/api/source_info_pb2.py +6 -4
  78. py2docfx/venv/venv1/Lib/site-packages/google/api/system_parameter_pb2.py +6 -3
  79. py2docfx/venv/venv1/Lib/site-packages/google/api/usage_pb2.py +6 -3
  80. py2docfx/venv/venv1/Lib/site-packages/google/api/visibility_pb2.py +7 -5
  81. py2docfx/venv/venv1/Lib/site-packages/google/cloud/extended_operations_pb2.py +6 -4
  82. py2docfx/venv/venv1/Lib/site-packages/google/cloud/location/locations_pb2.py +18 -13
  83. py2docfx/venv/venv1/Lib/site-packages/google/gapic/metadata/gapic_metadata_pb2.py +31 -26
  84. py2docfx/venv/venv1/Lib/site-packages/google/logging/type/http_request_pb2.py +6 -4
  85. py2docfx/venv/venv1/Lib/site-packages/google/logging/type/log_severity_pb2.py +6 -3
  86. py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_grpc.py +2 -1
  87. py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_grpc_pb2.py +11 -10
  88. py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_pb2.py +20 -17
  89. py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_pb2_grpc.py +1 -2
  90. py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_proto.py +2 -1
  91. py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_proto_pb2.py +22 -19
  92. py2docfx/venv/venv1/Lib/site-packages/google/rpc/code_pb2.py +6 -3
  93. py2docfx/venv/venv1/Lib/site-packages/google/rpc/context/attribute_context_pb2.py +20 -16
  94. py2docfx/venv/venv1/Lib/site-packages/google/rpc/context/audit_context_pb2.py +7 -5
  95. py2docfx/venv/venv1/Lib/site-packages/google/rpc/error_details_pb2.py +21 -19
  96. py2docfx/venv/venv1/Lib/site-packages/google/rpc/http_pb2.py +6 -3
  97. py2docfx/venv/venv1/Lib/site-packages/google/rpc/status_pb2.py +6 -4
  98. py2docfx/venv/venv1/Lib/site-packages/google/type/calendar_period_pb2.py +6 -3
  99. py2docfx/venv/venv1/Lib/site-packages/google/type/color_pb2.py +6 -4
  100. py2docfx/venv/venv1/Lib/site-packages/google/type/date_pb2.py +6 -3
  101. py2docfx/venv/venv1/Lib/site-packages/google/type/datetime_pb2.py +6 -4
  102. py2docfx/venv/venv1/Lib/site-packages/google/type/dayofweek_pb2.py +6 -3
  103. py2docfx/venv/venv1/Lib/site-packages/google/type/decimal_pb2.py +6 -3
  104. py2docfx/venv/venv1/Lib/site-packages/google/type/expr_pb2.py +6 -3
  105. py2docfx/venv/venv1/Lib/site-packages/google/type/fraction_pb2.py +6 -3
  106. py2docfx/venv/venv1/Lib/site-packages/google/type/interval_pb2.py +6 -4
  107. py2docfx/venv/venv1/Lib/site-packages/google/type/latlng_pb2.py +6 -3
  108. py2docfx/venv/venv1/Lib/site-packages/google/type/localized_text_pb2.py +6 -3
  109. py2docfx/venv/venv1/Lib/site-packages/google/type/money_pb2.py +6 -3
  110. py2docfx/venv/venv1/Lib/site-packages/google/type/month_pb2.py +6 -3
  111. py2docfx/venv/venv1/Lib/site-packages/google/type/phone_number_pb2.py +6 -3
  112. py2docfx/venv/venv1/Lib/site-packages/google/type/postal_address_pb2.py +6 -3
  113. py2docfx/venv/venv1/Lib/site-packages/google/type/quaternion_pb2.py +6 -3
  114. py2docfx/venv/venv1/Lib/site-packages/google/type/timeofday_pb2.py +6 -3
  115. py2docfx/venv/venv1/Lib/site-packages/psutil/__init__.py +122 -201
  116. py2docfx/venv/venv1/Lib/site-packages/psutil/_common.py +84 -128
  117. py2docfx/venv/venv1/Lib/site-packages/psutil/_psaix.py +24 -38
  118. py2docfx/venv/venv1/Lib/site-packages/psutil/_psbsd.py +44 -58
  119. py2docfx/venv/venv1/Lib/site-packages/psutil/_pslinux.py +170 -254
  120. py2docfx/venv/venv1/Lib/site-packages/psutil/_psosx.py +8 -16
  121. py2docfx/venv/venv1/Lib/site-packages/psutil/_psposix.py +13 -49
  122. py2docfx/venv/venv1/Lib/site-packages/psutil/_pssunos.py +41 -60
  123. py2docfx/venv/venv1/Lib/site-packages/psutil/_pswindows.py +75 -145
  124. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/__init__.py +105 -193
  125. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_aix.py +2 -2
  126. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_bsd.py +27 -26
  127. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_connections.py +16 -17
  128. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_contracts.py +5 -19
  129. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_linux.py +153 -211
  130. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_memleaks.py +0 -6
  131. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_misc.py +22 -207
  132. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_osx.py +9 -4
  133. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_posix.py +8 -15
  134. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_process.py +104 -184
  135. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_process_all.py +28 -36
  136. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_scripts.py +240 -0
  137. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_sunos.py +1 -1
  138. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_system.py +44 -50
  139. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_testutils.py +23 -33
  140. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_unicode.py +8 -67
  141. py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_windows.py +32 -52
  142. {py2docfx-0.1.11rc1981066.dist-info → py2docfx-0.1.11rc1997820.dist-info}/METADATA +1 -1
  143. {py2docfx-0.1.11rc1981066.dist-info → py2docfx-0.1.11rc1997820.dist-info}/RECORD +145 -145
  144. py2docfx/venv/venv1/Lib/site-packages/psutil/_compat.py +0 -477
  145. {py2docfx-0.1.11rc1981066.dist-info → py2docfx-0.1.11rc1997820.dist-info}/WHEEL +0 -0
  146. {py2docfx-0.1.11rc1981066.dist-info → py2docfx-0.1.11rc1997820.dist-info}/top_level.txt +0 -0
@@ -1,19 +1,19 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
4
2
  # Use of this source code is governed by a BSD-style license that can be
5
3
  # found in the LICENSE file.
6
4
 
7
5
  """Test utilities."""
8
6
 
9
- from __future__ import print_function
10
7
 
11
8
  import atexit
12
9
  import contextlib
13
10
  import ctypes
11
+ import enum
14
12
  import errno
15
13
  import functools
16
14
  import gc
15
+ import importlib
16
+ import ipaddress
17
17
  import os
18
18
  import platform
19
19
  import random
@@ -56,28 +56,7 @@ from psutil._common import debug
56
56
  from psutil._common import memoize
57
57
  from psutil._common import print_color
58
58
  from psutil._common import supports_ipv6
59
- from psutil._compat import PY3
60
- from psutil._compat import FileExistsError
61
- from psutil._compat import FileNotFoundError
62
- from psutil._compat import range
63
- from psutil._compat import super
64
- from psutil._compat import unicode
65
- from psutil._compat import which
66
-
67
-
68
- try:
69
- from unittest import mock # py3
70
- except ImportError:
71
- with warnings.catch_warnings():
72
- warnings.simplefilter("ignore")
73
- import mock # NOQA - requires "pip install mock"
74
59
 
75
- if PY3:
76
- import enum
77
- else:
78
- import unittest2 as unittest
79
-
80
- enum = None
81
60
 
82
61
  if POSIX:
83
62
  from psutil._psposix import wait_pid
@@ -86,7 +65,7 @@ if POSIX:
86
65
  # fmt: off
87
66
  __all__ = [
88
67
  # constants
89
- 'APPVEYOR', 'DEVNULL', 'GLOBAL_TIMEOUT', 'TOLERANCE_SYS_MEM', 'NO_RETRIES',
68
+ 'DEVNULL', 'GLOBAL_TIMEOUT', 'TOLERANCE_SYS_MEM', 'NO_RETRIES',
90
69
  'PYPY', 'PYTHON_EXE', 'PYTHON_EXE_ENV', 'ROOT_DIR', 'SCRIPTS_DIR',
91
70
  'TESTFN_PREFIX', 'UNICODE_SUFFIX', 'INVALID_UNICODE_SUFFIX',
92
71
  'CI_TESTING', 'VALID_PROC_STATUSES', 'TOLERANCE_DISK_USAGE', 'IS_64BIT',
@@ -94,7 +73,7 @@ __all__ = [
94
73
  "HAS_IONICE", "HAS_MEMORY_MAPS", "HAS_PROC_CPU_NUM", "HAS_RLIMIT",
95
74
  "HAS_SENSORS_BATTERY", "HAS_BATTERY", "HAS_SENSORS_FANS",
96
75
  "HAS_SENSORS_TEMPERATURES", "HAS_NET_CONNECTIONS_UNIX", "MACOS_11PLUS",
97
- "MACOS_12PLUS", "COVERAGE", 'AARCH64', "QEMU_USER", "PYTEST_PARALLEL",
76
+ "MACOS_12PLUS", "COVERAGE", 'AARCH64', "PYTEST_PARALLEL",
98
77
  # subprocesses
99
78
  'pyrun', 'terminate', 'reap_children', 'spawn_testproc', 'spawn_zombie',
100
79
  'spawn_children_pair',
@@ -131,16 +110,10 @@ __all__ = [
131
110
 
132
111
  PYPY = '__pypy__' in sys.builtin_module_names
133
112
  # whether we're running this test suite on a Continuous Integration service
134
- APPVEYOR = 'APPVEYOR' in os.environ
135
113
  GITHUB_ACTIONS = 'GITHUB_ACTIONS' in os.environ or 'CIBUILDWHEEL' in os.environ
136
- CI_TESTING = APPVEYOR or GITHUB_ACTIONS
114
+ CI_TESTING = GITHUB_ACTIONS
137
115
  COVERAGE = 'COVERAGE_RUN' in os.environ
138
116
  PYTEST_PARALLEL = "PYTEST_XDIST_WORKER" in os.environ # `make test-parallel`
139
- if LINUX and GITHUB_ACTIONS:
140
- with open('/proc/1/cmdline') as f:
141
- QEMU_USER = "/bin/qemu-" in f.read()
142
- else:
143
- QEMU_USER = False
144
117
  # are we a 64 bit process?
145
118
  IS_64BIT = sys.maxsize > 2**32
146
119
  AARCH64 = platform.machine() == "aarch64"
@@ -196,16 +169,13 @@ if CI_TESTING:
196
169
  # Disambiguate TESTFN for parallel testing.
197
170
  if os.name == 'java':
198
171
  # Jython disallows @ in module names
199
- TESTFN_PREFIX = '$psutil-%s-' % os.getpid()
172
+ TESTFN_PREFIX = f"$psutil-{os.getpid()}-"
200
173
  else:
201
- TESTFN_PREFIX = '@psutil-%s-' % os.getpid()
202
- UNICODE_SUFFIX = u"-ƒőő"
174
+ TESTFN_PREFIX = f"@psutil-{os.getpid()}-"
175
+ UNICODE_SUFFIX = "-ƒőő"
203
176
  # An invalid unicode string.
204
- if PY3:
205
- INVALID_UNICODE_SUFFIX = b"f\xc0\x80".decode('utf8', 'surrogateescape')
206
- else:
207
- INVALID_UNICODE_SUFFIX = "f\xc0\x80"
208
- ASCII_FS = sys.getfilesystemencoding().lower() in {'ascii', 'us-ascii'}
177
+ INVALID_UNICODE_SUFFIX = b"f\xc0\x80".decode('utf8', 'surrogateescape')
178
+ ASCII_FS = sys.getfilesystemencoding().lower() in {"ascii", "us-ascii"}
209
179
 
210
180
  # --- paths
211
181
 
@@ -273,7 +243,9 @@ def _get_py_exe():
273
243
  exe = (
274
244
  attempt(sys.executable)
275
245
  or attempt(os.path.realpath(sys.executable))
276
- or attempt(which("python%s.%s" % sys.version_info[:2]))
246
+ or attempt(
247
+ shutil.which("python{}.{}".format(*sys.version_info[:2]))
248
+ )
277
249
  or attempt(psutil.Process().exe())
278
250
  )
279
251
  if not exe:
@@ -286,7 +258,7 @@ def _get_py_exe():
286
258
 
287
259
 
288
260
  PYTHON_EXE, PYTHON_EXE_ENV = _get_py_exe()
289
- DEVNULL = open(os.devnull, 'r+')
261
+ DEVNULL = open(os.devnull, 'r+') # noqa: SIM115
290
262
  atexit.register(DEVNULL.close)
291
263
 
292
264
  VALID_PROC_STATUSES = [
@@ -314,7 +286,7 @@ class ThreadTask(threading.Thread):
314
286
 
315
287
  def __repr__(self):
316
288
  name = self.__class__.__name__
317
- return '<%s running=%s at %#x>' % (name, self._running, id(self))
289
+ return f"<{name} running={self._running} at {id(self):#x}>"
318
290
 
319
291
  def __enter__(self):
320
292
  self.start()
@@ -389,8 +361,8 @@ def spawn_testproc(cmd=None, **kwds):
389
361
  safe_rmpath(testfn)
390
362
  pyline = (
391
363
  "import time;"
392
- + "open(r'%s', 'w').close();" % testfn
393
- + "[time.sleep(0.1) for x in range(100)];" # 10 secs
364
+ f"open(r'{testfn}', 'w').close();"
365
+ "[time.sleep(0.1) for x in range(100)];" # 10 secs
394
366
  )
395
367
  cmd = [PYTHON_EXE, "-c", pyline]
396
368
  sproc = subprocess.Popen(cmd, **kwds)
@@ -416,16 +388,16 @@ def spawn_children_pair():
416
388
  tfile = None
417
389
  testfn = get_testfn(dir=os.getcwd())
418
390
  try:
419
- s = textwrap.dedent("""\
391
+ s = textwrap.dedent(f"""\
420
392
  import subprocess, os, sys, time
421
393
  s = "import os, time;"
422
- s += "f = open('%s', 'w');"
394
+ s += "f = open('{os.path.basename(testfn)}', 'w');"
423
395
  s += "f.write(str(os.getpid()));"
424
396
  s += "f.close();"
425
397
  s += "[time.sleep(0.1) for x in range(100 * 6)];"
426
- p = subprocess.Popen([r'%s', '-c', s])
398
+ p = subprocess.Popen([r'{PYTHON_EXE}', '-c', s])
427
399
  p.wait()
428
- """ % (os.path.basename(testfn), PYTHON_EXE))
400
+ """)
429
401
  # On Windows if we create a subprocess with CREATE_NO_WINDOW flag
430
402
  # set (which is the default) a "conhost.exe" extra process will be
431
403
  # spawned as a child. We don't want that.
@@ -451,22 +423,18 @@ def spawn_zombie():
451
423
  """
452
424
  assert psutil.POSIX
453
425
  unix_file = get_testfn()
454
- src = textwrap.dedent("""\
426
+ src = textwrap.dedent(f"""\
455
427
  import os, sys, time, socket, contextlib
456
428
  child_pid = os.fork()
457
429
  if child_pid > 0:
458
430
  time.sleep(3000)
459
431
  else:
460
432
  # this is the zombie process
461
- s = socket.socket(socket.AF_UNIX)
462
- with contextlib.closing(s):
463
- s.connect('%s')
464
- if sys.version_info < (3, ):
465
- pid = str(os.getpid())
466
- else:
467
- pid = bytes(str(os.getpid()), 'ascii')
433
+ with socket.socket(socket.AF_UNIX) as s:
434
+ s.connect('{unix_file}')
435
+ pid = bytes(str(os.getpid()), 'ascii')
468
436
  s.sendall(pid)
469
- """ % unix_file)
437
+ """)
470
438
  tfile = None
471
439
  sock = bind_unix_socket(unix_file)
472
440
  try:
@@ -524,10 +492,7 @@ def sh(cmd, **kwds):
524
492
  cmd = shlex.split(cmd)
525
493
  p = subprocess.Popen(cmd, **kwds)
526
494
  _subprocesses_started.add(p)
527
- if PY3:
528
- stdout, stderr = p.communicate(timeout=GLOBAL_TIMEOUT)
529
- else:
530
- stdout, stderr = p.communicate()
495
+ stdout, stderr = p.communicate(timeout=GLOBAL_TIMEOUT)
531
496
  if p.returncode != 0:
532
497
  raise RuntimeError(stdout + stderr)
533
498
  if stderr:
@@ -549,10 +514,7 @@ def terminate(proc_or_pid, sig=signal.SIGTERM, wait_timeout=GLOBAL_TIMEOUT):
549
514
  """
550
515
 
551
516
  def wait(proc, timeout):
552
- if isinstance(proc, subprocess.Popen) and not PY3:
553
- proc.wait()
554
- else:
555
- proc.wait(timeout)
517
+ proc.wait(timeout)
556
518
  if WINDOWS and isinstance(proc, subprocess.Popen):
557
519
  # Otherwise PID may still hang around.
558
520
  try:
@@ -573,11 +535,12 @@ def terminate(proc_or_pid, sig=signal.SIGTERM, wait_timeout=GLOBAL_TIMEOUT):
573
535
  def term_subprocess_proc(proc, timeout):
574
536
  try:
575
537
  sendsig(proc, sig)
538
+ except ProcessLookupError:
539
+ pass
576
540
  except OSError as err:
577
541
  if WINDOWS and err.winerror == 6: # "invalid handle"
578
542
  pass
579
- elif err.errno != errno.ESRCH:
580
- raise
543
+ raise
581
544
  return wait(proc, timeout)
582
545
 
583
546
  def term_psutil_proc(proc, timeout):
@@ -615,7 +578,7 @@ def terminate(proc_or_pid, sig=signal.SIGTERM, wait_timeout=GLOBAL_TIMEOUT):
615
578
  elif isinstance(p, subprocess.Popen):
616
579
  return term_subprocess_proc(p, wait_timeout)
617
580
  else:
618
- raise TypeError("wrong type %r" % p)
581
+ raise TypeError(f"wrong type {p!r}")
619
582
  finally:
620
583
  if isinstance(p, (subprocess.Popen, psutil.Popen)):
621
584
  flush_popen(p)
@@ -651,7 +614,7 @@ def reap_children(recursive=False):
651
614
  terminate(p, wait_timeout=None)
652
615
  _, alive = psutil.wait_procs(children, timeout=GLOBAL_TIMEOUT)
653
616
  for p in alive:
654
- warn("couldn't terminate process %r; attempting kill()" % p)
617
+ warn(f"couldn't terminate process {p!r}; attempting kill()")
655
618
  terminate(p, sig=signal.SIGKILL)
656
619
 
657
620
 
@@ -672,7 +635,7 @@ def kernel_version():
672
635
  else:
673
636
  break
674
637
  if not s:
675
- raise ValueError("can't parse %r" % uname)
638
+ raise ValueError(f"can't parse {uname!r}")
676
639
  minor = 0
677
640
  micro = 0
678
641
  nums = s.split('.')
@@ -688,11 +651,7 @@ def get_winver():
688
651
  if not WINDOWS:
689
652
  raise NotImplementedError("not WINDOWS")
690
653
  wv = sys.getwindowsversion()
691
- if hasattr(wv, 'service_pack_major'): # python >= 2.7
692
- sp = wv.service_pack_major or 0
693
- else:
694
- r = re.search(r"\s\d$", wv[4])
695
- sp = int(r.group(0)) if r else 0
654
+ sp = wv.service_pack_major or 0
696
655
  return (wv[0], wv[1], sp)
697
656
 
698
657
 
@@ -743,16 +702,14 @@ class retry:
743
702
  for _ in self:
744
703
  try:
745
704
  return fun(*args, **kwargs)
746
- except self.exception as _: # NOQA
705
+ except self.exception as _:
747
706
  exc = _
748
707
  if self.logfun is not None:
749
708
  self.logfun(exc)
750
709
  self.sleep()
751
710
  continue
752
- if PY3:
753
- raise exc # noqa: PLE0704
754
- else:
755
- raise # noqa: PLE0704
711
+
712
+ raise exc
756
713
 
757
714
  # This way the user of the decorated function can change config
758
715
  # parameters.
@@ -824,9 +781,9 @@ def safe_rmpath(path):
824
781
  return fun()
825
782
  except FileNotFoundError:
826
783
  pass
827
- except WindowsError as _:
784
+ except OSError as _:
828
785
  err = _
829
- warn("ignoring %s" % (str(err)))
786
+ warn(f"ignoring {err}")
830
787
  time.sleep(0.01)
831
788
  raise err
832
789
 
@@ -877,7 +834,7 @@ def create_py_exe(path):
877
834
  def create_c_exe(path, c_code=None):
878
835
  """Create a compiled C executable in the given location."""
879
836
  assert not os.path.exists(path), path
880
- if not which("gcc"):
837
+ if not shutil.which("gcc"):
881
838
  raise pytest.skip("gcc is not installed")
882
839
  if c_code is None:
883
840
  c_code = textwrap.dedent("""
@@ -928,7 +885,7 @@ class fake_pytest:
928
885
  """
929
886
 
930
887
  @staticmethod
931
- def main(*args, **kw): # noqa ARG004
888
+ def main(*args, **kw): # noqa: ARG004
932
889
  """Mimics pytest.main(). It has the same effect as running
933
890
  `python3 -m unittest -v` from the project root directory.
934
891
  """
@@ -959,11 +916,11 @@ class fake_pytest:
959
916
  yield einfo
960
917
  except exc as err:
961
918
  if match and not re.search(match, str(err)):
962
- msg = '"{}" does not match "{}"'.format(match, str(err))
919
+ msg = f'"{match}" does not match "{err}"'
963
920
  raise AssertionError(msg)
964
921
  einfo._exc = err
965
922
  else:
966
- raise AssertionError("%r not raised" % exc)
923
+ raise AssertionError(f"{exc!r} not raised")
967
924
 
968
925
  return context(exc, match=match)
969
926
 
@@ -1000,24 +957,7 @@ if pytest is None:
1000
957
  pytest = fake_pytest
1001
958
 
1002
959
 
1003
- class TestCase(unittest.TestCase):
1004
- # ...otherwise multiprocessing.Pool complains
1005
- if not PY3:
1006
-
1007
- def runTest(self):
1008
- pass
1009
-
1010
- @contextlib.contextmanager
1011
- def subTest(self, *args, **kw):
1012
- # fake it for python 2.7
1013
- yield
1014
-
1015
-
1016
- # monkey patch default unittest.TestCase
1017
- unittest.TestCase = TestCase
1018
-
1019
-
1020
- class PsutilTestCase(TestCase):
960
+ class PsutilTestCase(unittest.TestCase):
1021
961
  """Test class providing auto-cleanup wrappers on top of process
1022
962
  test utilities. All test classes should derive from this one, even
1023
963
  if we use pytest.
@@ -1088,9 +1028,9 @@ class PsutilTestCase(TestCase):
1088
1028
  except psutil.NoSuchProcess as exc:
1089
1029
  self._check_proc_exc(proc, exc)
1090
1030
  else:
1091
- msg = "Process.%s() didn't raise NSP and returned %r" % (
1092
- name,
1093
- ret,
1031
+ msg = (
1032
+ f"Process.{name}() didn't raise NSP and returned"
1033
+ f" {ret!r}"
1094
1034
  )
1095
1035
  raise AssertionError(msg)
1096
1036
  proc.wait(timeout=0) # assert not raise TimeoutExpired
@@ -1236,15 +1176,16 @@ class TestMemoryLeak(PsutilTestCase):
1236
1176
  after = self._get_num_fds()
1237
1177
  diff = after - before
1238
1178
  if diff < 0:
1239
- raise self.fail(
1240
- "negative diff %r (gc probably collected a "
1241
- "resource from a previous test)" % diff
1179
+ msg = (
1180
+ f"negative diff {diff!r} (gc probably collected a"
1181
+ " resource from a previous test)"
1242
1182
  )
1183
+ raise self.fail(msg)
1243
1184
  if diff > 0:
1244
1185
  type_ = "fd" if POSIX else "handle"
1245
1186
  if diff > 1:
1246
1187
  type_ += "s"
1247
- msg = "%s unclosed %s after calling %r" % (diff, type_, fun)
1188
+ msg = f"{diff} unclosed {type_} after calling {fun!r}"
1248
1189
  raise self.fail(msg)
1249
1190
 
1250
1191
  def _call_ntimes(self, fun, times):
@@ -1268,7 +1209,7 @@ class TestMemoryLeak(PsutilTestCase):
1268
1209
  increase = times
1269
1210
  for idx in range(1, retries + 1):
1270
1211
  mem = self._call_ntimes(fun, times)
1271
- msg = "Run #%s: extra-mem=%s, per-call=%s, calls=%s" % (
1212
+ msg = "Run #{}: extra-mem={}, per-call={}, calls={}".format(
1272
1213
  idx,
1273
1214
  bytes2human(mem),
1274
1215
  bytes2human(mem / times),
@@ -1282,7 +1223,7 @@ class TestMemoryLeak(PsutilTestCase):
1282
1223
  return
1283
1224
  else:
1284
1225
  if idx == 1:
1285
- print() # NOQA
1226
+ print() # noqa: T201
1286
1227
  self._log(msg)
1287
1228
  times += increase
1288
1229
  prev_mem = mem
@@ -1345,16 +1286,16 @@ def print_sysinfo():
1345
1286
  info = collections.OrderedDict()
1346
1287
 
1347
1288
  # OS
1348
- if psutil.LINUX and which('lsb_release'):
1289
+ if psutil.LINUX and shutil.which("lsb_release"):
1349
1290
  info['OS'] = sh('lsb_release -d -s')
1350
1291
  elif psutil.OSX:
1351
- info['OS'] = 'Darwin %s' % platform.mac_ver()[0]
1292
+ info['OS'] = f"Darwin {platform.mac_ver()[0]}"
1352
1293
  elif psutil.WINDOWS:
1353
1294
  info['OS'] = "Windows " + ' '.join(map(str, platform.win32_ver()))
1354
1295
  if hasattr(platform, 'win32_edition'):
1355
1296
  info['OS'] += ", " + platform.win32_edition()
1356
1297
  else:
1357
- info['OS'] = "%s %s" % (platform.system(), platform.version())
1298
+ info['OS'] = f"{platform.system()} {platform.version()}"
1358
1299
  info['arch'] = ', '.join(
1359
1300
  list(platform.architecture()) + [platform.machine()]
1360
1301
  )
@@ -1369,11 +1310,11 @@ def print_sysinfo():
1369
1310
  ])
1370
1311
  info['pip'] = getattr(pip, '__version__', 'not installed')
1371
1312
  if wheel is not None:
1372
- info['pip'] += " (wheel=%s)" % wheel.__version__
1313
+ info['pip'] += f" (wheel={wheel.__version__})"
1373
1314
 
1374
1315
  # UNIX
1375
1316
  if psutil.POSIX:
1376
- if which('gcc'):
1317
+ if shutil.which("gcc"):
1377
1318
  out = sh(['gcc', '--version'])
1378
1319
  info['gcc'] = str(out).split('\n')[0]
1379
1320
  else:
@@ -1385,7 +1326,7 @@ def print_sysinfo():
1385
1326
  # system
1386
1327
  info['fs-encoding'] = sys.getfilesystemencoding()
1387
1328
  lang = locale.getlocale()
1388
- info['lang'] = '%s, %s' % (lang[0], lang[1])
1329
+ info['lang'] = f"{lang[0]}, {lang[1]}"
1389
1330
  info['boot-time'] = datetime.datetime.fromtimestamp(
1390
1331
  psutil.boot_time()
1391
1332
  ).strftime("%Y-%m-%d %H:%M:%S")
@@ -1399,17 +1340,17 @@ def print_sysinfo():
1399
1340
 
1400
1341
  # metrics
1401
1342
  info['cpus'] = psutil.cpu_count()
1402
- info['loadavg'] = "%.1f%%, %.1f%%, %.1f%%" % (
1403
- tuple([x / psutil.cpu_count() * 100 for x in psutil.getloadavg()])
1343
+ info['loadavg'] = "{:.1f}%, {:.1f}%, {:.1f}%".format(
1344
+ *tuple(x / psutil.cpu_count() * 100 for x in psutil.getloadavg())
1404
1345
  )
1405
1346
  mem = psutil.virtual_memory()
1406
- info['memory'] = "%s%%, used=%s, total=%s" % (
1347
+ info['memory'] = "{}%%, used={}, total={}".format(
1407
1348
  int(mem.percent),
1408
1349
  bytes2human(mem.used),
1409
1350
  bytes2human(mem.total),
1410
1351
  )
1411
1352
  swap = psutil.swap_memory()
1412
- info['swap'] = "%s%%, used=%s, total=%s" % (
1353
+ info['swap'] = "{}%%, used={}, total={}".format(
1413
1354
  int(swap.percent),
1414
1355
  bytes2human(swap.used),
1415
1356
  bytes2human(swap.total),
@@ -1419,17 +1360,17 @@ def print_sysinfo():
1419
1360
  pinfo.pop('memory_maps', None)
1420
1361
  info['proc'] = pprint.pformat(pinfo)
1421
1362
 
1422
- print("=" * 70, file=sys.stderr) # NOQA
1363
+ print("=" * 70, file=sys.stderr) # noqa: T201
1423
1364
  for k, v in info.items():
1424
- print("%-17s %s" % (k + ':', v), file=sys.stderr) # NOQA
1425
- print("=" * 70, file=sys.stderr) # NOQA
1365
+ print("{:<17} {}".format(k + ":", v), file=sys.stderr) # noqa: T201
1366
+ print("=" * 70, file=sys.stderr) # noqa: T201
1426
1367
  sys.stdout.flush()
1427
1368
 
1428
1369
  # if WINDOWS:
1429
1370
  # os.system("tasklist")
1430
- # elif which("ps"):
1371
+ # elif shutil.which("ps"):
1431
1372
  # os.system("ps aux")
1432
- # print("=" * 70, file=sys.stderr) # NOQA
1373
+ # print("=" * 70, file=sys.stderr)
1433
1374
 
1434
1375
  sys.stdout.flush()
1435
1376
 
@@ -1478,7 +1419,6 @@ class process_namespace:
1478
1419
  ('children', (), {'recursive': True}),
1479
1420
  ('connections', (), {}), # deprecated
1480
1421
  ('is_running', (), {}),
1481
- ('memory_info_ex', (), {}), # deprecated
1482
1422
  ('oneshot', (), {}),
1483
1423
  ('parent', (), {}),
1484
1424
  ('parents', (), {}),
@@ -1583,20 +1523,20 @@ class process_namespace:
1583
1523
  for fun_name, _, _ in ls:
1584
1524
  meth_name = 'test_' + fun_name
1585
1525
  if not hasattr(test_class, meth_name):
1586
- msg = "%r class should define a '%s' method" % (
1587
- test_class.__class__.__name__,
1588
- meth_name,
1526
+ msg = (
1527
+ f"{test_class.__class__.__name__!r} class should define a"
1528
+ f" {meth_name!r} method"
1589
1529
  )
1590
1530
  raise AttributeError(msg)
1591
1531
 
1592
1532
  @classmethod
1593
1533
  def test(cls):
1594
- this = set([x[0] for x in cls.all])
1595
- ignored = set([x[0] for x in cls.ignored])
1596
- klass = set([x for x in dir(psutil.Process) if x[0] != '_'])
1534
+ this = {x[0] for x in cls.all}
1535
+ ignored = {x[0] for x in cls.ignored}
1536
+ klass = {x for x in dir(psutil.Process) if x[0] != '_'}
1597
1537
  leftout = (this | ignored) ^ klass
1598
1538
  if leftout:
1599
- raise ValueError("uncovered Process class names: %r" % leftout)
1539
+ raise ValueError(f"uncovered Process class names: {leftout!r}")
1600
1540
 
1601
1541
 
1602
1542
  class system_namespace:
@@ -1675,7 +1615,7 @@ def retry_on_failure(retries=NO_RETRIES):
1675
1615
  """
1676
1616
 
1677
1617
  def logfun(exc):
1678
- print("%r, retrying" % exc, file=sys.stderr) # NOQA
1618
+ print(f"{exc!r}, retrying", file=sys.stderr) # noqa: T201
1679
1619
 
1680
1620
  return retry(
1681
1621
  exception=AssertionError, timeout=None, retries=retries, logfun=logfun
@@ -1714,8 +1654,8 @@ def skip_on_not_implemented(only_if=None):
1714
1654
  if not only_if:
1715
1655
  raise
1716
1656
  msg = (
1717
- "%r was skipped because it raised NotImplementedError"
1718
- % fun.__name__
1657
+ f"{fun.__name__!r} was skipped because it raised"
1658
+ " NotImplementedError"
1719
1659
  )
1720
1660
  raise pytest.skip(msg)
1721
1661
 
@@ -1732,7 +1672,7 @@ def skip_on_not_implemented(only_if=None):
1732
1672
  # XXX: no longer used
1733
1673
  def get_free_port(host='127.0.0.1'):
1734
1674
  """Return an unused TCP port. Subject to race conditions."""
1735
- with contextlib.closing(socket.socket()) as sock:
1675
+ with socket.socket() as sock:
1736
1676
  sock.bind((host, 0))
1737
1677
  return sock.getsockname()[1]
1738
1678
 
@@ -1773,7 +1713,7 @@ def tcp_socketpair(family, addr=("", 0)):
1773
1713
  """Build a pair of TCP sockets connected to each other.
1774
1714
  Return a (server, client) tuple.
1775
1715
  """
1776
- with contextlib.closing(socket.socket(family, SOCK_STREAM)) as ll:
1716
+ with socket.socket(family, SOCK_STREAM) as ll:
1777
1717
  ll.bind(addr)
1778
1718
  ll.listen(5)
1779
1719
  addr = ll.getsockname()
@@ -1821,11 +1761,15 @@ def create_sockets():
1821
1761
  socks = []
1822
1762
  fname1 = fname2 = None
1823
1763
  try:
1824
- socks.append(bind_socket(socket.AF_INET, socket.SOCK_STREAM))
1825
- socks.append(bind_socket(socket.AF_INET, socket.SOCK_DGRAM))
1764
+ socks.extend((
1765
+ bind_socket(socket.AF_INET, socket.SOCK_STREAM),
1766
+ bind_socket(socket.AF_INET, socket.SOCK_DGRAM),
1767
+ ))
1826
1768
  if supports_ipv6():
1827
- socks.append(bind_socket(socket.AF_INET6, socket.SOCK_STREAM))
1828
- socks.append(bind_socket(socket.AF_INET6, socket.SOCK_DGRAM))
1769
+ socks.extend((
1770
+ bind_socket(socket.AF_INET6, socket.SOCK_STREAM),
1771
+ bind_socket(socket.AF_INET6, socket.SOCK_DGRAM),
1772
+ ))
1829
1773
  if POSIX and HAS_NET_CONNECTIONS_UNIX:
1830
1774
  fname1 = get_testfn()
1831
1775
  fname2 = get_testfn()
@@ -1846,27 +1790,20 @@ def check_net_address(addr, family):
1846
1790
  """Check a net address validity. Supported families are IPv4,
1847
1791
  IPv6 and MAC addresses.
1848
1792
  """
1849
- import ipaddress # python >= 3.3 / requires "pip install ipaddress"
1850
-
1851
- if enum and PY3 and not PYPY:
1852
- assert isinstance(family, enum.IntEnum), family
1793
+ assert isinstance(family, enum.IntEnum), family
1853
1794
  if family == socket.AF_INET:
1854
1795
  octs = [int(x) for x in addr.split('.')]
1855
1796
  assert len(octs) == 4, addr
1856
1797
  for num in octs:
1857
1798
  assert 0 <= num <= 255, addr
1858
- if not PY3:
1859
- addr = unicode(addr)
1860
1799
  ipaddress.IPv4Address(addr)
1861
1800
  elif family == socket.AF_INET6:
1862
1801
  assert isinstance(addr, str), addr
1863
- if not PY3:
1864
- addr = unicode(addr)
1865
1802
  ipaddress.IPv6Address(addr)
1866
1803
  elif family == psutil.AF_LINK:
1867
1804
  assert re.match(r'([a-fA-F0-9]{2}[:|\-]?){6}', addr) is not None, addr
1868
1805
  else:
1869
- raise ValueError("unknown family %r" % family)
1806
+ raise ValueError(f"unknown family {family!r}")
1870
1807
 
1871
1808
 
1872
1809
  def check_connection_ntuple(conn):
@@ -1886,20 +1823,16 @@ def check_connection_ntuple(conn):
1886
1823
 
1887
1824
  def check_family(conn):
1888
1825
  assert conn.family in {AF_INET, AF_INET6, AF_UNIX}, conn.family
1889
- if enum is not None:
1890
- assert isinstance(conn.family, enum.IntEnum), conn
1891
- else:
1892
- assert isinstance(conn.family, int), conn
1826
+ assert isinstance(conn.family, enum.IntEnum), conn
1893
1827
  if conn.family == AF_INET:
1894
1828
  # actually try to bind the local socket; ignore IPv6
1895
1829
  # sockets as their address might be represented as
1896
1830
  # an IPv4-mapped-address (e.g. "::127.0.0.1")
1897
1831
  # and that's rejected by bind()
1898
- s = socket.socket(conn.family, conn.type)
1899
- with contextlib.closing(s):
1832
+ with socket.socket(conn.family, conn.type) as s:
1900
1833
  try:
1901
1834
  s.bind((conn.laddr[0], 0))
1902
- except socket.error as err:
1835
+ except OSError as err:
1903
1836
  if err.errno != errno.EADDRNOTAVAIL:
1904
1837
  raise
1905
1838
  elif conn.family == AF_UNIX:
@@ -1913,10 +1846,7 @@ def check_connection_ntuple(conn):
1913
1846
  socket.SOCK_DGRAM,
1914
1847
  SOCK_SEQPACKET,
1915
1848
  }, conn.type
1916
- if enum is not None:
1917
- assert isinstance(conn.type, enum.IntEnum), conn
1918
- else:
1919
- assert isinstance(conn.type, int), conn
1849
+ assert isinstance(conn.type, enum.IntEnum), conn
1920
1850
  if conn.type == socket.SOCK_DGRAM:
1921
1851
  assert conn.status == psutil.CONN_NONE, conn.status
1922
1852
 
@@ -1959,45 +1889,27 @@ def filter_proc_net_connections(cons):
1959
1889
  for conn in cons:
1960
1890
  if POSIX and conn.family == socket.AF_UNIX:
1961
1891
  if MACOS and "/syslog" in conn.raddr:
1962
- debug("skipping %s" % str(conn))
1892
+ debug(f"skipping {conn}")
1963
1893
  continue
1964
1894
  new.append(conn)
1965
1895
  return new
1966
1896
 
1967
1897
 
1968
1898
  # ===================================================================
1969
- # --- compatibility
1899
+ # --- import utils
1970
1900
  # ===================================================================
1971
1901
 
1972
1902
 
1973
1903
  def reload_module(module):
1974
- """Backport of importlib.reload of Python 3.3+."""
1975
- try:
1976
- import importlib
1977
-
1978
- if not hasattr(importlib, 'reload'): # python <=3.3
1979
- raise ImportError
1980
- except ImportError:
1981
- import imp
1982
-
1983
- return imp.reload(module)
1984
- else:
1985
- return importlib.reload(module)
1904
+ return importlib.reload(module)
1986
1905
 
1987
1906
 
1988
1907
  def import_module_by_path(path):
1989
1908
  name = os.path.splitext(os.path.basename(path))[0]
1990
- if sys.version_info[0] < 3:
1991
- import imp
1992
-
1993
- return imp.load_source(name, path)
1994
- else:
1995
- import importlib.util
1996
-
1997
- spec = importlib.util.spec_from_file_location(name, path)
1998
- mod = importlib.util.module_from_spec(spec)
1999
- spec.loader.exec_module(mod)
2000
- return mod
1909
+ spec = importlib.util.spec_from_file_location(name, path)
1910
+ mod = importlib.util.module_from_spec(spec)
1911
+ spec.loader.exec_module(mod)
1912
+ return mod
2001
1913
 
2002
1914
 
2003
1915
  # ===================================================================
@@ -2090,7 +2002,7 @@ else:
2090
2002
  FreeLibrary.argtypes = [wintypes.HMODULE]
2091
2003
  ret = FreeLibrary(cfile._handle)
2092
2004
  if ret == 0:
2093
- WinError()
2005
+ raise WinError()
2094
2006
  safe_rmpath(dst)
2095
2007
 
2096
2008