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
@@ -6,6 +6,7 @@ import shutil
6
6
  import stat
7
7
  import pytest
8
8
  import sys
9
+
9
10
  from py2docfx.convert_prepare import git
10
11
  from py2docfx.convert_prepare import get_source
11
12
  from py2docfx.convert_prepare.package_info import PackageInfo
@@ -61,7 +62,8 @@ def test_update_package_info(init_package_info):
61
62
  assert package.name == "mock_package"
62
63
  assert package.version == "1.2.0"
63
64
 
64
- def test_get_source_git_clone(init_package_info):
65
+ @pytest.mark.asyncio
66
+ async def test_get_source_git_clone(init_package_info):
65
67
  """
66
68
  Test the git clone of get_source
67
69
  """
@@ -76,10 +78,11 @@ def test_get_source_git_clone(init_package_info):
76
78
  package.branch = "main"
77
79
  package.folder = None
78
80
  package.url = "https://github.com/Azure/azure-iot-hub-python"
79
- get_source.get_source(sys.executable, package, 0)
81
+ await get_source.get_source(sys.executable, package, 0)
80
82
  assert git.status("source_repo/0") is True
81
83
 
82
- def test_get_source_dist_file_zip(init_package_info):
84
+ @pytest.mark.asyncio
85
+ async def test_get_source_dist_file_zip(init_package_info):
83
86
  """
84
87
  Test the zip dist file download of get_source
85
88
  """
@@ -92,12 +95,13 @@ def test_get_source_dist_file_zip(init_package_info):
92
95
  package.extra_index_url = None
93
96
  package.prefer_source_distribution = True
94
97
  package.location = "https://files.pythonhosted.org/packages/3e/71/f6f71a276e2e69264a97ad39ef850dca0a04fce67b12570730cb38d0ccac/azure-common-1.1.28.zip"
95
- get_source.get_source(sys.executable, package, 1)
98
+ await get_source.get_source(sys.executable, package, 1)
96
99
  assert os.path.exists("dist_temp/1/azure-common-1.1.28")
97
100
  assert package.path.source_folder == os.path.join("dist_temp", "1", "azure-common-1.1.28")
98
101
  assert os.path.exists("dist_temp/1/azure-common-1.1.28.zip") is False
99
102
 
100
- def test_get_source_dist_file_whl(init_package_info):
103
+ @pytest.mark.asyncio
104
+ async def test_get_source_dist_file_whl(init_package_info):
101
105
  """
102
106
  Test the whl dist file download of get_source
103
107
  """
@@ -110,12 +114,13 @@ def test_get_source_dist_file_whl(init_package_info):
110
114
  package.extra_index_url = None
111
115
  package.prefer_source_distribution = True
112
116
  package.location = "https://files.pythonhosted.org/packages/62/55/7f118b9c1b23ec15ca05d15a578d8207aa1706bc6f7c87218efffbbf875d/azure_common-1.1.28-py2.py3-none-any.whl"
113
- get_source.get_source(sys.executable, package, 2)
117
+ await get_source.get_source(sys.executable, package, 2)
114
118
  assert os.path.exists("dist_temp/2/azure_common-1.1.28")
115
119
  assert package.path.source_folder == os.path.join("dist_temp", "2", "azure_common-1.1.28")
116
120
  assert os.path.exists("dist_temp/2/azure_common-1.1.28-py2.py3-none-any.whl") is False
117
121
 
118
- def test_get_source_dist_file_tar(init_package_info):
122
+ @pytest.mark.asyncio
123
+ async def test_get_source_dist_file_tar(init_package_info):
119
124
  """
120
125
  Test the tar dist file download of get_source
121
126
  """
@@ -128,12 +133,13 @@ def test_get_source_dist_file_tar(init_package_info):
128
133
  package.extra_index_url = None
129
134
  package.prefer_source_distribution = True
130
135
  package.location = "https://files.pythonhosted.org/packages/fa/19/43a9eb812b4d6071fdc2c55640318f7eb5a1be8dbd3b6f9d96a1996e1bb6/azure-core-1.29.4.tar.gz"
131
- get_source.get_source(sys.executable, package, 3)
136
+ await get_source.get_source(sys.executable, package, 3)
132
137
  assert os.path.exists("dist_temp/3/azure-core-1.29.4")
133
138
  assert package.path.source_folder == os.path.join("dist_temp", "3", "azure-core-1.29.4")
134
139
  assert os.path.exists("dist_temp/3/azure-core-1.29.4.tar.gz") is False
135
140
 
136
- def test_get_source_pip_whl(init_package_info):
141
+ @pytest.mark.asyncio
142
+ async def test_get_source_pip_whl(init_package_info):
137
143
  """
138
144
  Test the pip install of get_source with prefer_source_distribution = False
139
145
  """
@@ -145,12 +151,13 @@ def test_get_source_pip_whl(init_package_info):
145
151
  package.build_in_subpackage = False
146
152
  package.extra_index_url = None
147
153
  package.prefer_source_distribution = False
148
- get_source.get_source(sys.executable, package, 4)
154
+ await get_source.get_source(sys.executable, package, 4)
149
155
  assert os.path.exists("dist_temp/4/azure_common-1.1.28")
150
156
  assert package.path.source_folder == os.path.join("dist_temp", "4", "azure_common-1.1.28")
151
157
  assert os.path.exists("dist_temp/4/azure_common-1.1.28-py2.py3-none-any.whl") is False
152
158
 
153
- def test_get_source_pip_zip(init_package_info):
159
+ @pytest.mark.asyncio
160
+ async def test_get_source_pip_zip(init_package_info):
154
161
  """
155
162
  Test the pip install of get_source with prefer_source_distribution = True
156
163
  """
@@ -162,12 +169,13 @@ def test_get_source_pip_zip(init_package_info):
162
169
  package.build_in_subpackage = False
163
170
  package.extra_index_url = None
164
171
  package.prefer_source_distribution = True
165
- get_source.get_source(sys.executable, package, 5)
172
+ await get_source.get_source(sys.executable, package, 5)
166
173
  assert os.path.exists("dist_temp/5/azure-common-1.1.28")
167
174
  assert package.path.source_folder == os.path.join("dist_temp", "5", "azure-common-1.1.28")
168
175
  assert os.path.exists("dist_temp/5/azure-common-1.1.28.zip") is False
169
176
 
170
- def test_get_source_zip_file_at_position_0(init_package_info):
177
+ @pytest.mark.asyncio
178
+ async def test_get_source_zip_file_at_position_0(init_package_info):
171
179
  """
172
180
  Test the pip install of packages with zip or tar file at position 0 in the dirctory list
173
181
  """
@@ -179,7 +187,7 @@ def test_get_source_zip_file_at_position_0(init_package_info):
179
187
  package.build_in_subpackage = False
180
188
  package.extra_index_url = None
181
189
  package.prefer_source_distribution = True
182
- get_source.get_source(sys.executable, package, 6)
190
+ await get_source.get_source(sys.executable, package, 6)
183
191
  assert os.path.exists("dist_temp/6/azure_template-0.1.0b3942895")
184
192
  assert package.path.source_folder == os.path.join("dist_temp", "6", "azure_template-0.1.0b3942895")
185
193
  assert os.path.exists("dist_temp/6/azure_template-0.1.0b3942895.tar.gz") is False
@@ -5,6 +5,8 @@ import subprocess
5
5
  import shutil
6
6
  import glob
7
7
  from os import path
8
+ import pytest
9
+
8
10
  from py2docfx.convert_prepare.pack import unpack_compressed, unpack_wheel
9
11
 
10
12
  SRC_DIR = path.abspath("convert_prepare/tests/data/pack/")
@@ -81,8 +83,8 @@ def test_pack_unpack_compressed(tmp_path):
81
83
  path.abspath("convert_prepare/tests/data/pack"), tmp_path / "gz", [], [str(gz_file_path)]
82
84
  )
83
85
 
84
-
85
- def test_pack_unpack_wheel(tmp_path):
86
+ @pytest.mark.asyncio
87
+ async def test_pack_unpack_wheel(tmp_path):
86
88
  def _prepare_wheel(target_path):
87
89
  subprocess.run(
88
90
  ["pip", "wheel", ".", "--wheel-dir", str(target_path / "wheel")],
@@ -107,7 +109,8 @@ def test_pack_unpack_wheel(tmp_path):
107
109
  wheel_path = path.join(tmp_path / "wheel", wheel_name)
108
110
 
109
111
  # unpack and assert the file list
110
- unpack_wheel(wheel_path)
112
+ package_name = wheel_name.split("-")[0]
113
+ await unpack_wheel(package_name, wheel_path)
111
114
  _assert_file_list_same(
112
115
  path.abspath("convert_prepare/tests/data/pack"),
113
116
  tmp_path / "wheel" / "foo-0.1",
@@ -1,4 +1,3 @@
1
- import pytest
2
1
  import os
3
2
 
4
3
  from py2docfx.convert_prepare.params import load_file_params, load_command_params
@@ -1,5 +1,5 @@
1
- import pytest
2
1
  import os
2
+ import pytest
3
3
  import shutil
4
4
  import sphinx
5
5
  import sphinx.cmd.build
@@ -24,20 +24,22 @@ def init_paths(tmp_path):
24
24
  package_info.name = 'testcode'
25
25
  return rst_path, destination
26
26
 
27
-
28
- def test_run_apidoc(tmp_path):
27
+ @pytest.mark.asyncio
28
+ async def test_run_apidoc(tmp_path):
29
29
  rst_path, source_code_path = init_paths(tmp_path)
30
- run_apidoc(rst_path, source_code_path, package_info.get_exluded_command(), package_info)
30
+ package_name = "testcode"
31
+ await run_apidoc(package_name, rst_path, source_code_path, package_info.get_exluded_command(), package_info)
31
32
 
32
33
  # List all files under rst_path
33
34
  rst_list = os.listdir(rst_path)
34
35
  assert "testcode.fakemodule.rst" in rst_list
35
36
  assert "testcode.exclude.rst" not in rst_list
36
37
 
37
-
38
- def test_run_converter(tmp_path):
38
+ @pytest.mark.asyncio
39
+ async def test_run_converter(tmp_path):
39
40
  rst_path, source_code_path = init_paths(tmp_path)
40
- run_apidoc(rst_path, source_code_path, package_info.get_exluded_command(), package_info)
41
+ package_name = "testcode"
42
+ await run_apidoc(package_name, rst_path, source_code_path, package_info.get_exluded_command(), package_info)
41
43
 
42
44
  # prepare conf.py, index.rst and docfx_yaml
43
45
  conf_path = os.path.abspath("convert_prepare/tests/data/sphinx_caller/conf.py")
@@ -49,7 +51,7 @@ def test_run_converter(tmp_path):
49
51
  index_rst.write("")
50
52
 
51
53
  out_path = os.path.join(tmp_path, "out")
52
- out_path = run_converter(rst_path, out_path, sphinx_build_path = sphinx.cmd.build.__file__, extra_package_path = source_code_path, conf_path=rst_path)
54
+ out_path = await run_converter(package_name, rst_path, out_path, sphinx_build_path = sphinx.cmd.build.__file__, extra_package_path = source_code_path, conf_path=rst_path)
53
55
 
54
56
  if os.path.exists(out_path):
55
57
  yaml_list = os.listdir(os.path.join(out_path, "docfx_yaml"))
@@ -1,5 +1,6 @@
1
1
  import shutil, os, yaml
2
2
  from os import path
3
+
3
4
  from py2docfx.convert_prepare.subpackage import (
4
5
  get_subpackages,
5
6
  move_rst_files_to_subfolder,
@@ -315,7 +315,7 @@ def build_finished(app, exception):
315
315
  if len(toc_yaml) == 0:
316
316
  msg = "No documentation for this module."
317
317
  py2docfx_logger.error(msg)
318
- raise RuntimeError()
318
+ raise RuntimeError(msg)
319
319
 
320
320
  toc_file = os.path.join(normalized_outdir, 'toc.yml')
321
321
  with open(toc_file, 'w') as writable:
@@ -34,8 +34,13 @@ def check_log_file_exists(log_file_path):
34
34
  with open(log_file_path, 'w') as f:
35
35
  f.write('')
36
36
 
37
- def setup_log_handlers(logger, log_file_name):
37
+ def setup_log_handlers(logger_name, log_file_name, log_folder_path):
38
+ check_log_dir_exists(log_folder_path)
39
+ logger = logging.getLogger(logger_name)
40
+ logger.setLevel(logging.INFO)
38
41
  check_log_file_exists(log_file_name)
42
+ if logger.hasHandlers():
43
+ logger.handlers.clear()
39
44
  file_handler = logging.FileHandler(filename=log_file_name, mode='a')
40
45
  file_handler.setFormatter(logging.Formatter('%(levelname)s - %(name)s - %(message)s'))
41
46
  logger.addHandler(file_handler)
@@ -45,57 +50,20 @@ def setup_log_handlers(logger, log_file_name):
45
50
  def get_logger(logger_name: str):
46
51
  log_folder_path = os.path.join("logs")
47
52
  file_name = os.path.join(log_folder_path, "log.txt")
48
-
49
- file_logger = logging.getLogger(logger_name)
50
- file_logger.setLevel(logging.INFO)
51
- check_log_dir_exists(log_folder_path)
52
- if file_logger.hasHandlers():
53
- return file_logger
54
-
55
- file_logger = setup_log_handlers(file_logger, file_name)
53
+
54
+ file_logger = setup_log_handlers(logger_name, file_name, log_folder_path)
56
55
 
57
56
  return file_logger
58
57
 
59
- def get_package_logger(logger_name:str):
58
+ def get_package_logger(logger_name:str, package_name:str = None):
60
59
  log_folder_path = os.path.join("logs", "package_logs")
61
- package_name = os.environ.get('PROCESSING_PACKAGE_NAME')
60
+ if package_name is None:
61
+ package_name = os.environ.get('PROCESSING_PACKAGE_NAME')
62
62
  file_name = os.path.join(log_folder_path, f"{package_name}.txt")
63
-
64
- file_logger = logging.getLogger(logger_name)
65
- file_logger.setLevel(logging.INFO)
66
- check_log_dir_exists(log_folder_path)
67
- if file_logger.hasHandlers():
68
- return file_logger
69
63
 
70
- file_logger = setup_log_handlers(file_logger, file_name)
71
-
72
- return file_logger
64
+ file_logger = setup_log_handlers(logger_name, file_name, log_folder_path)
73
65
 
74
- def log_subprocess_ouput(subprocess_out: subprocess.CompletedProcess, logger: logging.Logger):
75
- if subprocess_out.stdout:
76
- logger.info(subprocess_out.stdout)
77
- if subprocess_out.stderr:
78
- msgs = subprocess_out.stderr.split('\n')
79
- for msg in msgs:
80
- if msg is None or msg == "":
81
- continue
82
- logger.warning(msg)
83
- if subprocess_out.returncode != 0:
84
- logger.error(f"Subprocess failed with return code {subprocess_out.returncode}")
85
- raise RuntimeError()
86
-
87
- def log_git_clone_subprocess_ouput(subprocess_out: subprocess.CompletedProcess, logger: logging.Logger):
88
- if subprocess_out.stdout:
89
- logger.info(subprocess_out.stdout)
90
- if subprocess_out.stderr:
91
- msgs = subprocess_out.stderr.split('\n')
92
- for msg in msgs:
93
- if msg is None or msg == "":
94
- continue
95
- logger.info(msg)
96
- if subprocess_out.returncode != 0:
97
- logger.error(f"Subprocess failed with return code {subprocess_out.returncode}")
98
- raise RuntimeError()
66
+ return file_logger
99
67
 
100
68
  def counts_errors_warnings(log_file_path):
101
69
  error_count = 0
@@ -160,20 +128,53 @@ def output_log_by_log_level():
160
128
  log_file_path = os.path.join(package_logs_folder, log_file)
161
129
  print_out_log_by_log_level(parse_log(log_file_path), log_level)
162
130
 
163
- async def run_async_subprocess(exe_path, cmd):
164
- process = await asyncio.create_subprocess_exec(
165
- exe_path, *cmd,
166
- stdout=asyncio.subprocess.PIPE,
167
- stderr=asyncio.subprocess.PIPE
168
- )
131
+ async def run_async_subprocess(exe_path, cmd, logger, cwd=None):
132
+ if cwd is None:
133
+ process = await asyncio.create_subprocess_exec(
134
+ exe_path, *cmd,
135
+ stdout=asyncio.subprocess.PIPE,
136
+ stderr=asyncio.subprocess.PIPE
137
+ )
138
+ else:
139
+ process = await asyncio.create_subprocess_exec(
140
+ exe_path, *cmd,
141
+ cwd=cwd,
142
+ stdout=asyncio.subprocess.PIPE,
143
+ stderr=asyncio.subprocess.PIPE,
144
+ )
145
+ stdout, stderr = await process.communicate()
146
+ if process.returncode != 0:
147
+ msg = stderr.decode('utf-8')
148
+ if msg != None and msg != "":
149
+ logger.error(msg)
150
+ raise subprocess.CalledProcessError(process.returncode, cmd, stdout, stderr)
151
+ else:
152
+ msg = stdout.decode('utf-8')
153
+ if msg != None and msg != "":
154
+ logger.info(msg)
155
+
156
+ async def run_async_subprocess_without_executable(cmd, logger, cwd=None):
157
+ if cwd is None:
158
+ process = await asyncio.create_subprocess_exec(
159
+ *cmd,
160
+ stdout=asyncio.subprocess.PIPE,
161
+ stderr=asyncio.subprocess.PIPE
162
+ )
163
+ else:
164
+ process = await asyncio.create_subprocess_exec(
165
+ *cmd,
166
+ cwd=cwd,
167
+ stdout=asyncio.subprocess.PIPE,
168
+ stderr=asyncio.subprocess.PIPE,
169
+ )
170
+
169
171
  stdout, stderr = await process.communicate()
170
- py2docfx_logger = get_logger(__name__)
171
172
  if process.returncode != 0:
172
173
  msg = stderr.decode('utf-8')
173
174
  if msg != None and msg != "":
174
- py2docfx_logger.error(msg)
175
- raise RuntimeError()
175
+ logger.error(msg)
176
+ raise subprocess.CalledProcessError(process.returncode, cmd, stdout, stderr)
176
177
  else:
177
178
  msg = stdout.decode('utf-8')
178
179
  if msg != None and msg != "":
179
- py2docfx_logger.info(msg)
180
+ logger.info(msg)
@@ -85,7 +85,7 @@ class AuthorizationCodeCredential(GetTokenMixin):
85
85
  attribute gives a reason. Any error response from Microsoft Entra ID is available as the error's
86
86
  ``response`` attribute.
87
87
  """
88
- # pylint:disable=useless-super-delegation
88
+
89
89
  return super(AuthorizationCodeCredential, self).get_token(
90
90
  *scopes, claims=claims, tenant_id=tenant_id, client_secret=self._client_secret, **kwargs
91
91
  )
@@ -5,6 +5,7 @@
5
5
 
6
6
  from datetime import datetime
7
7
  import json
8
+ import logging
8
9
  import os
9
10
  import re
10
11
  import shutil
@@ -19,12 +20,15 @@ from .. import CredentialUnavailableError
19
20
  from .._internal import resolve_tenant, within_dac, validate_tenant_id, validate_scope
20
21
  from .._internal.decorators import log_get_token
21
22
 
23
+
24
+ _LOGGER = logging.getLogger(__name__)
25
+
22
26
  CLI_NOT_FOUND = (
23
27
  "Azure Developer CLI could not be found. "
24
28
  "Please visit https://aka.ms/azure-dev for installation instructions and then,"
25
29
  "once installed, authenticate to your Azure account using 'azd auth login'."
26
30
  )
27
- COMMAND_LINE = "azd auth token --output json --scope {}"
31
+ COMMAND_LINE = ["auth", "token", "--output", "json"]
28
32
  EXECUTABLE_NAME = "azd"
29
33
  NOT_LOGGED_IN = "Please run 'azd auth login' from a command prompt to authenticate before using this credential."
30
34
 
@@ -160,8 +164,9 @@ class AzureDeveloperCliCredential:
160
164
  for scope in scopes:
161
165
  validate_scope(scope)
162
166
 
163
- commandString = " --scope ".join(scopes)
164
- command = COMMAND_LINE.format(commandString)
167
+ command_args = COMMAND_LINE.copy()
168
+ for scope in scopes:
169
+ command_args += ["--scope", scope]
165
170
  tenant = resolve_tenant(
166
171
  default_tenant=self.tenant_id,
167
172
  tenant_id=tenant_id,
@@ -169,8 +174,8 @@ class AzureDeveloperCliCredential:
169
174
  **kwargs,
170
175
  )
171
176
  if tenant:
172
- command += " --tenant-id " + tenant
173
- output = _run_command(command, self._process_timeout)
177
+ command_args += ["--tenant-id", tenant]
178
+ output = _run_command(command_args, self._process_timeout)
174
179
 
175
180
  token = parse_token(output)
176
181
  if not token:
@@ -236,15 +241,13 @@ def sanitize_output(output: str) -> str:
236
241
  return re.sub(r"\"token\": \"(.*?)(\"|$)", "****", output)
237
242
 
238
243
 
239
- def _run_command(command: str, timeout: int) -> str:
244
+ def _run_command(command_args: List[str], timeout: int) -> str:
240
245
  # Ensure executable exists in PATH first. This avoids a subprocess call that would fail anyway.
241
- if shutil.which(EXECUTABLE_NAME) is None:
246
+ azd_path = shutil.which(EXECUTABLE_NAME)
247
+ if not azd_path:
242
248
  raise CredentialUnavailableError(message=CLI_NOT_FOUND)
243
249
 
244
- if sys.platform.startswith("win"):
245
- args = ["cmd", "/c", command]
246
- else:
247
- args = ["/bin/sh", "-c", command]
250
+ args = [azd_path] + command_args
248
251
  try:
249
252
  working_directory = get_safe_working_dir()
250
253
 
@@ -257,13 +260,16 @@ def _run_command(command: str, timeout: int) -> str:
257
260
  "timeout": timeout,
258
261
  }
259
262
 
263
+ _LOGGER.debug("Executing subprocess with the following arguments %s", args)
260
264
  return subprocess.check_output(args, **kwargs)
261
265
  except subprocess.CalledProcessError as ex:
262
266
  # non-zero return from shell
263
267
  # Fallback check in case the executable is not found while executing subprocess.
264
- if ex.returncode == 127 or ex.stderr.startswith("'azd' is not recognized"):
268
+ if ex.returncode == 127 or (ex.stderr is not None and ex.stderr.startswith("'azd' is not recognized")):
265
269
  raise CredentialUnavailableError(message=CLI_NOT_FOUND) from ex
266
- if "not logged in, run `azd auth login` to login" in ex.stderr and "AADSTS" not in ex.stderr:
270
+ if ex.stderr is not None and (
271
+ "not logged in, run `azd auth login` to login" in ex.stderr and "AADSTS" not in ex.stderr
272
+ ):
267
273
  raise CredentialUnavailableError(message=NOT_LOGGED_IN) from ex
268
274
 
269
275
  # return code is from the CLI -> propagate its output
@@ -278,7 +284,7 @@ def _run_command(command: str, timeout: int) -> str:
278
284
  # failed to execute 'cmd' or '/bin/sh'
279
285
  error = CredentialUnavailableError(message="Failed to execute '{}'".format(args[0]))
280
286
  raise error from ex
281
- except Exception as ex: # pylint:disable=broad-except
287
+ except Exception as ex:
282
288
  # could be a timeout, for example
283
289
  error = CredentialUnavailableError(message="Failed to invoke the Azure Developer CLI")
284
290
  raise error from ex
@@ -54,7 +54,7 @@ def _get_secret_key(response: PipelineResponse) -> str:
54
54
  with open(key_file, "r", encoding="utf-8") as file:
55
55
  try:
56
56
  return file.read()
57
- except Exception as error: # pylint:disable=broad-except
57
+ except Exception as error:
58
58
  # user is expected to have obtained read permission prior to this being called
59
59
  raise ClientAuthenticationError(
60
60
  message="Could not read file {} contents: {}".format(key_file, error)
@@ -6,6 +6,7 @@ from datetime import datetime
6
6
  import json
7
7
  import os
8
8
  import re
9
+ import logging
9
10
  import shutil
10
11
  import subprocess
11
12
  import sys
@@ -15,12 +16,22 @@ from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOpt
15
16
  from azure.core.exceptions import ClientAuthenticationError
16
17
 
17
18
  from .. import CredentialUnavailableError
18
- from .._internal import _scopes_to_resource, resolve_tenant, within_dac, validate_tenant_id, validate_scope
19
+ from .._internal import (
20
+ _scopes_to_resource,
21
+ resolve_tenant,
22
+ within_dac,
23
+ validate_tenant_id,
24
+ validate_scope,
25
+ validate_subscription,
26
+ )
19
27
  from .._internal.decorators import log_get_token
20
28
 
21
29
 
30
+ _LOGGER = logging.getLogger(__name__)
31
+
22
32
  CLI_NOT_FOUND = "Azure CLI not found on path"
23
- COMMAND_LINE = "az account get-access-token --output json --resource {}"
33
+ # COMMAND_LINE = "account get-access-token --output json --resource {}"
34
+ COMMAND_LINE = ["account", "get-access-token", "--output", "json"]
24
35
  EXECUTABLE_NAME = "az"
25
36
  NOT_LOGGED_IN = "Please run 'az login' to set up an account"
26
37
 
@@ -31,6 +42,8 @@ class AzureCliCredential:
31
42
  This requires previously logging in to Azure via "az login", and will use the CLI's currently logged in identity.
32
43
 
33
44
  :keyword str tenant_id: Optional tenant to include in the token request.
45
+ :keyword str subscription: The name or ID of a subscription. Set this to acquire tokens for an account other
46
+ than the Azure CLI's current account.
34
47
  :keyword List[str] additionally_allowed_tenants: Specifies tenants in addition to the specified "tenant_id"
35
48
  for which the credential may acquire tokens. Add the wildcard value "*" to allow the credential to
36
49
  acquire tokens for any tenant the application can access.
@@ -50,12 +63,17 @@ class AzureCliCredential:
50
63
  self,
51
64
  *,
52
65
  tenant_id: str = "",
66
+ subscription: Optional[str] = None,
53
67
  additionally_allowed_tenants: Optional[List[str]] = None,
54
68
  process_timeout: int = 10,
55
69
  ) -> None:
56
70
  if tenant_id:
57
71
  validate_tenant_id(tenant_id)
72
+ if subscription:
73
+ validate_subscription(subscription)
74
+
58
75
  self.tenant_id = tenant_id
76
+ self.subscription = subscription
59
77
  self._additionally_allowed_tenants = additionally_allowed_tenants or []
60
78
  self._process_timeout = process_timeout
61
79
 
@@ -135,7 +153,7 @@ class AzureCliCredential:
135
153
  validate_scope(scope)
136
154
 
137
155
  resource = _scopes_to_resource(*scopes)
138
- command = COMMAND_LINE.format(resource)
156
+ command_args = COMMAND_LINE + ["--resource", resource]
139
157
  tenant = resolve_tenant(
140
158
  default_tenant=self.tenant_id,
141
159
  tenant_id=tenant_id,
@@ -143,8 +161,11 @@ class AzureCliCredential:
143
161
  **kwargs,
144
162
  )
145
163
  if tenant:
146
- command += " --tenant " + tenant
147
- output = _run_command(command, self._process_timeout)
164
+ command_args += ["--tenant", tenant]
165
+
166
+ if self.subscription:
167
+ command_args += ["--subscription", self.subscription]
168
+ output = _run_command(command_args, self._process_timeout)
148
169
 
149
170
  token = parse_token(output)
150
171
  if not token:
@@ -211,15 +232,13 @@ def sanitize_output(output: str) -> str:
211
232
  return re.sub(r"\"accessToken\": \"(.*?)(\"|$)", "****", output)
212
233
 
213
234
 
214
- def _run_command(command: str, timeout: int) -> str:
235
+ def _run_command(command_args: List[str], timeout: int) -> str:
215
236
  # Ensure executable exists in PATH first. This avoids a subprocess call that would fail anyway.
216
- if shutil.which(EXECUTABLE_NAME) is None:
237
+ az_path = shutil.which(EXECUTABLE_NAME)
238
+ if not az_path:
217
239
  raise CredentialUnavailableError(message=CLI_NOT_FOUND)
218
240
 
219
- if sys.platform.startswith("win"):
220
- args = ["cmd", "/c", command]
221
- else:
222
- args = ["/bin/sh", "-c", command]
241
+ args = [az_path] + command_args
223
242
  try:
224
243
  working_directory = get_safe_working_dir()
225
244
 
@@ -231,13 +250,16 @@ def _run_command(command: str, timeout: int) -> str:
231
250
  "timeout": timeout,
232
251
  "env": dict(os.environ, AZURE_CORE_NO_COLOR="true"),
233
252
  }
253
+ _LOGGER.debug("Executing subprocess with the following arguments %s", args)
234
254
  return subprocess.check_output(args, **kwargs)
235
255
  except subprocess.CalledProcessError as ex:
236
256
  # non-zero return from shell
237
257
  # Fallback check in case the executable is not found while executing subprocess.
238
- if ex.returncode == 127 or ex.stderr.startswith("'az' is not recognized"):
258
+ if ex.returncode == 127 or (ex.stderr is not None and ex.stderr.startswith("'az' is not recognized")):
239
259
  raise CredentialUnavailableError(message=CLI_NOT_FOUND) from ex
240
- if ("az login" in ex.stderr or "az account set" in ex.stderr) and "AADSTS" not in ex.stderr:
260
+ if ex.stderr is not None and (
261
+ ("az login" in ex.stderr or "az account set" in ex.stderr) and "AADSTS" not in ex.stderr
262
+ ):
241
263
  raise CredentialUnavailableError(message=NOT_LOGGED_IN) from ex
242
264
 
243
265
  # return code is from the CLI -> propagate its output
@@ -252,7 +274,7 @@ def _run_command(command: str, timeout: int) -> str:
252
274
  # failed to execute 'cmd' or '/bin/sh'
253
275
  error = CredentialUnavailableError(message="Failed to execute '{}'".format(args[0]))
254
276
  raise error from ex
255
- except Exception as ex: # pylint:disable=broad-except
277
+ except Exception as ex:
256
278
  # could be a timeout, for example
257
279
  error = CredentialUnavailableError(message="Failed to invoke the Azure CLI")
258
280
  raise error from ex
@@ -192,7 +192,7 @@ def run_command_line(command_line: List[str], timeout: int) -> str:
192
192
  proc = start_process(command_line)
193
193
  stdout, stderr = proc.communicate(**kwargs)
194
194
 
195
- except Exception as ex: # pylint:disable=broad-except
195
+ except Exception as ex:
196
196
  # failed to execute "cmd" or "/bin/sh", or timed out; PowerShell and Az.Account may or may not be installed
197
197
  # (handling Exception here because subprocess.SubprocessError and .TimeoutExpired were added in 3.3)
198
198
  if proc and not proc.returncode:
@@ -37,8 +37,8 @@ class ChainedTokenCredential:
37
37
  """A sequence of credentials that is itself a credential.
38
38
 
39
39
  Its :func:`get_token` method calls ``get_token`` on each credential in the sequence, in order, returning the first
40
- valid token received. For more information, see
41
- https://aka.ms/azsdk/python/identity/credential-chains#chainedtokencredential-overview.
40
+ valid token received. For more information, see `ChainedTokenCredential overview
41
+ <"https://aka.ms/azsdk/python/identity/credential-chains#chainedtokencredential-overview">`__.
42
42
 
43
43
  :param credentials: credential instances to form the chain
44
44
  :type credentials: ~azure.core.credentials.TokenCredential
@@ -24,8 +24,9 @@ _LOGGER = logging.getLogger(__name__)
24
24
 
25
25
 
26
26
  class DefaultAzureCredential(ChainedTokenCredential):
27
- """A credential capable of handling most Azure SDK authentication scenarios. See
28
- https://aka.ms/azsdk/python/identity/credential-chains#usage-guidance-for-defaultazurecredential.
27
+ """A credential capable of handling most Azure SDK authentication scenarios. For more information, See
28
+ `Usage guidance for DefaultAzureCredential
29
+ <"https://aka.ms/azsdk/python/identity/credential-chains#usage-guidance-for-defaultazurecredential">`__.
29
30
 
30
31
  The identity it uses depends on the environment. When an access token is needed, it requests one using these
31
32
  identities in turn, stopping when one provides a token:
@@ -153,7 +154,7 @@ class DefaultAzureCredential(ChainedTokenCredential):
153
154
  WorkloadIdentityCredential(
154
155
  client_id=cast(str, client_id),
155
156
  tenant_id=workload_identity_tenant_id,
156
- file=os.environ[EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE],
157
+ token_file_path=os.environ[EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE],
157
158
  **kwargs
158
159
  )
159
160
  )