py2docfx 0.1.9.dev1917798__py3-none-any.whl → 0.1.9.dev1927042__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 (78) hide show
  1. py2docfx/__main__.py +72 -23
  2. py2docfx/convert_prepare/conf_templates/conf.py_t +1 -1
  3. py2docfx/convert_prepare/constants.py +2 -1
  4. py2docfx/convert_prepare/environment.py +34 -13
  5. py2docfx/convert_prepare/generate_document.py +12 -5
  6. py2docfx/convert_prepare/get_source.py +5 -1
  7. py2docfx/convert_prepare/git.py +24 -20
  8. py2docfx/convert_prepare/package_info.py +15 -9
  9. py2docfx/convert_prepare/pip_utils.py +33 -8
  10. py2docfx/convert_prepare/post_process/merge_toc.py +5 -1
  11. py2docfx/convert_prepare/sphinx_caller.py +31 -14
  12. py2docfx/docfx_yaml/build_finished.py +11 -3
  13. py2docfx/docfx_yaml/convert_class.py +4 -2
  14. py2docfx/docfx_yaml/convert_enum.py +4 -2
  15. py2docfx/docfx_yaml/convert_module.py +4 -2
  16. py2docfx/docfx_yaml/convert_package.py +4 -2
  17. py2docfx/docfx_yaml/logger.py +141 -0
  18. py2docfx/docfx_yaml/process_doctree.py +6 -4
  19. py2docfx/docfx_yaml/translator.py +5 -7
  20. py2docfx/docfx_yaml/writer.py +10 -4
  21. py2docfx/docfx_yaml/yaml_builder.py +0 -1
  22. py2docfx/venv/basevenv/Lib/site-packages/setuptools/build_meta.py +2 -2
  23. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/bdist_egg.py +1 -1
  24. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/bdist_wheel.py +25 -39
  25. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/build_ext.py +2 -2
  26. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/build_py.py +9 -14
  27. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/easy_install.py +2 -2
  28. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/editable_wheel.py +2 -2
  29. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/egg_info.py +3 -2
  30. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/install_egg_info.py +2 -2
  31. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/saveopts.py +2 -2
  32. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/sdist.py +2 -2
  33. py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/setopt.py +1 -1
  34. py2docfx/venv/basevenv/Lib/site-packages/setuptools/config/pyprojecttoml.py +0 -13
  35. py2docfx/venv/basevenv/Lib/site-packages/setuptools/dist.py +3 -2
  36. py2docfx/venv/basevenv/Lib/site-packages/setuptools/monkey.py +3 -3
  37. py2docfx/venv/basevenv/Lib/site-packages/setuptools/msvc.py +11 -11
  38. py2docfx/venv/basevenv/Lib/site-packages/setuptools/tests/config/test_pyprojecttoml.py +0 -7
  39. py2docfx/venv/basevenv/Lib/site-packages/setuptools/tests/test_core_metadata.py +168 -72
  40. py2docfx/venv/basevenv/Lib/site-packages/setuptools/unicode_utils.py +3 -3
  41. py2docfx/venv/basevenv/Lib/site-packages/wheel/__init__.py +1 -1
  42. py2docfx/venv/basevenv/Lib/site-packages/wheel/cli/convert.py +1 -2
  43. py2docfx/venv/venv1/Lib/site-packages/jwt/__init__.py +3 -2
  44. py2docfx/venv/venv1/Lib/site-packages/jwt/algorithms.py +31 -16
  45. py2docfx/venv/venv1/Lib/site-packages/jwt/api_jws.py +19 -8
  46. py2docfx/venv/venv1/Lib/site-packages/jwt/api_jwt.py +75 -19
  47. py2docfx/venv/venv1/Lib/site-packages/jwt/exceptions.py +8 -0
  48. py2docfx/venv/venv1/Lib/site-packages/jwt/help.py +4 -1
  49. py2docfx/venv/venv1/Lib/site-packages/jwt/jwks_client.py +4 -2
  50. py2docfx/venv/venv1/Lib/site-packages/jwt/utils.py +7 -10
  51. py2docfx/venv/venv1/Lib/site-packages/msal/application.py +1 -1
  52. py2docfx/venv/venv1/Lib/site-packages/msal/managed_identity.py +5 -3
  53. py2docfx/venv/venv1/Lib/site-packages/setuptools/build_meta.py +2 -2
  54. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/bdist_egg.py +1 -1
  55. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/bdist_wheel.py +25 -39
  56. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/build_ext.py +2 -2
  57. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/build_py.py +9 -14
  58. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/easy_install.py +2 -2
  59. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/editable_wheel.py +2 -2
  60. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/egg_info.py +3 -2
  61. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/install_egg_info.py +2 -2
  62. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/saveopts.py +2 -2
  63. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/sdist.py +2 -2
  64. py2docfx/venv/venv1/Lib/site-packages/setuptools/command/setopt.py +1 -1
  65. py2docfx/venv/venv1/Lib/site-packages/setuptools/config/pyprojecttoml.py +0 -13
  66. py2docfx/venv/venv1/Lib/site-packages/setuptools/dist.py +3 -2
  67. py2docfx/venv/venv1/Lib/site-packages/setuptools/monkey.py +3 -3
  68. py2docfx/venv/venv1/Lib/site-packages/setuptools/msvc.py +11 -11
  69. py2docfx/venv/venv1/Lib/site-packages/setuptools/tests/config/test_pyprojecttoml.py +0 -7
  70. py2docfx/venv/venv1/Lib/site-packages/setuptools/tests/test_core_metadata.py +168 -72
  71. py2docfx/venv/venv1/Lib/site-packages/setuptools/unicode_utils.py +3 -3
  72. py2docfx/venv/venv1/Lib/site-packages/wheel/__init__.py +1 -1
  73. py2docfx/venv/venv1/Lib/site-packages/wheel/cli/convert.py +1 -2
  74. {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/METADATA +1 -1
  75. {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/RECORD +78 -77
  76. {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/WHEEL +1 -1
  77. /py2docfx/convert_prepare/conf_templates/{master_doc.rst_t → root_doc.rst_t} +0 -0
  78. {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/top_level.txt +0 -0
@@ -2,10 +2,13 @@ from __future__ import annotations # Avoid A | B annotation break under <= py3.9
2
2
  import os
3
3
  import shutil
4
4
 
5
+ from py2docfx.docfx_yaml.logger import get_logger
6
+
5
7
  TOC_FILE_PATH = "toc.yml"
6
8
  PACKAGE_TOC_FILE_PATH = "_build/docfx_yaml/toc.yml"
7
9
  def merge_toc(
8
10
  root_doc_path: str | os.PathLike, package_doc_path: str | os.PathLike):
11
+ py2docfx_logger = get_logger(__name__)
9
12
  root_toc_path = os.path.join(root_doc_path, TOC_FILE_PATH)
10
13
  package_toc_path = os.path.join(package_doc_path, PACKAGE_TOC_FILE_PATH)
11
14
 
@@ -18,7 +21,8 @@ def merge_toc(
18
21
  if not toc_content.endswith("\n"):
19
22
  root_toc_handle.write("\n")
20
23
  else:
21
- raise ValueError(f"TOC content empty: {package_toc_path}")
24
+ py2docfx_logger.error(f"TOC content empty: {package_toc_path}")
25
+ raise ValueError()
22
26
 
23
27
  # delete package toc.yml
24
28
  os.remove(package_toc_path)
@@ -5,6 +5,7 @@ import sphinx.ext.apidoc as apidoc
5
5
  import subprocess
6
6
 
7
7
  from py2docfx import PACKAGE_ROOT
8
+ from py2docfx.docfx_yaml.logger import get_package_logger,log_subprocess_ouput
8
9
  from py2docfx.convert_prepare.package_info import PackageInfo
9
10
  from py2docfx.convert_prepare.paths import folder_is_hidden
10
11
  from py2docfx.convert_prepare.subpackage import (get_subpackages,
@@ -19,6 +20,7 @@ def run_apidoc(rst_path, source_code_path, exclude_paths, package_info: PackageI
19
20
  Replacing
20
21
  https://apidrop.visualstudio.com/Content%20CI/_git/ReferenceAutomation?path=/Python/build.ps1&line=110&lineEnd=126&lineStartColumn=1&lineEndColumn=14&lineStyle=plain&_a=contents
21
22
  """
23
+ py2docfx_logger = get_package_logger(__name__)
22
24
  subfolderList = [name for name in
23
25
  os.listdir(source_code_path)
24
26
  if os.path.isdir(os.path.join(source_code_path, name))
@@ -28,16 +30,29 @@ def run_apidoc(rst_path, source_code_path, exclude_paths, package_info: PackageI
28
30
  for subfolder in subfolderList:
29
31
  subfolderPath = os.path.join(source_code_path, subfolder)
30
32
  if os.path.isdir(subfolderPath):
31
- print("<CI INFO>: Subfolder path {}.".format(subfolderPath))
32
- args = [
33
- "--module-first",
34
- "--no-headings",
35
- "--no-toc",
36
- "--implicit-namespaces",
37
- "-o",
38
- rst_path,
39
- subfolderPath,
40
- ]
33
+ msg = "<CI INFO>: Subfolder path {}.".format(subfolderPath)
34
+ py2docfx_logger.info(msg)
35
+ if os.environ.get('LOG_LEVEL') == 'INFO':
36
+ args = [
37
+ "--module-first",
38
+ "--no-headings",
39
+ "--no-toc",
40
+ "--implicit-namespaces",
41
+ "-o",
42
+ rst_path,
43
+ subfolderPath,
44
+ ]
45
+ else:
46
+ args = [
47
+ "-q",
48
+ "--module-first",
49
+ "--no-headings",
50
+ "--no-toc",
51
+ "--implicit-namespaces",
52
+ "-o",
53
+ rst_path,
54
+ subfolderPath
55
+ ]
41
56
  args.extend(exclude_paths)
42
57
  apidoc.main(args)
43
58
  if package_info.build_in_subpackage and subfolder == "azure":
@@ -56,14 +71,16 @@ def run_converter(rst_path, out_path, sphinx_build_path: str, extra_package_path
56
71
  Replacing
57
72
  https://apidrop.visualstudio.com/Content%20CI/_git/ReferenceAutomation?path=/Python/build.ps1&line=150&lineEnd=161&lineStartColumn=13&lineEndColumn=52&lineStyle=plain&_a=contents
58
73
  """
59
-
74
+ py2docfx_logger = get_package_logger(__name__)
60
75
  outdir = os.path.join(out_path, "_build")
61
76
 
62
77
  # Sphinx/docutils have memory leak including linecaches, module-import-caches,
63
78
  # Use a subprocess on production to prevent out of memory
64
79
 
65
80
  if not sys.executable:
66
- raise ValueError("Can't get the executable binary for the Python interpreter.")
81
+ msg = "Can't get the executable binary for the Python interpreter."
82
+ py2docfx_logger.error(msg)
83
+ raise ValueError()
67
84
  sphinx_param = [
68
85
  executable,
69
86
  sphinx_build_path,
@@ -82,6 +99,6 @@ def run_converter(rst_path, out_path, sphinx_build_path: str, extra_package_path
82
99
  env_tmp["PYTHONPATH"] = f"{extra_package_path};{package_root_parent};"
83
100
  else:
84
101
  env_tmp["PYTHONPATH"] = f"{extra_package_path}:{package_root_parent}:"
85
- subprocess.run(sphinx_param, check=True, cwd=PACKAGE_ROOT, env=env_tmp)
86
-
102
+ output = subprocess.run(sphinx_param, check=True, cwd=PACKAGE_ROOT, env=env_tmp, capture_output=True ,text=True)
103
+ log_subprocess_ouput(output, py2docfx_logger)
87
104
  return outdir
@@ -18,6 +18,7 @@ from convert_class import convert_class
18
18
  from convert_enum import convert_enum
19
19
  from convert_module import convert_module
20
20
  from convert_package import convert_package
21
+ from logger import get_package_logger
21
22
 
22
23
  INITPY = '__init__.py'
23
24
  MODULE = 'module'
@@ -91,6 +92,7 @@ def add_isrequired_if_needed(obj, key: str):
91
92
  args['isRequired'] = True
92
93
 
93
94
  def get_merged_params(obj, info_field_data, key: str):
95
+ py2docfx_logger = get_package_logger(__name__)
94
96
  merged_params = []
95
97
  arg_params = obj.get('syntax', {}).get(key, [])
96
98
  if key in info_field_data[obj['uid']]:
@@ -98,7 +100,8 @@ def get_merged_params(obj, info_field_data, key: str):
98
100
  key, [])
99
101
  if arg_params and doc_params:
100
102
  if len(arg_params) - len(doc_params) > 0:
101
- print(f'Documented params don\'t match size of params:{obj["uid"]}') # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
103
+ msg = f'Documented params don\'t match size of params:{obj["uid"]}' # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
104
+ py2docfx_logger.warning(msg)
102
105
  doc_params = remove_params_without_id(doc_params)
103
106
  merged_params = merge_params(arg_params, doc_params)
104
107
  else:
@@ -182,6 +185,8 @@ def build_finished(app, exception):
182
185
  """
183
186
  Output YAML on the file system.
184
187
  """
188
+
189
+ py2docfx_logger = get_package_logger(__name__)
185
190
 
186
191
  def convert_class_to_enum_if_needed(obj):
187
192
  if (obj.get('inheritance'), None):
@@ -299,7 +304,8 @@ def build_finished(app, exception):
299
304
  mime = "PythonModule"
300
305
 
301
306
  if transformed_obj == None:
302
- print(f"Unknown yml, uid is: {uid}")
307
+ msg = f"Unknown yml, uid is: {uid}"
308
+ py2docfx_logger.warning(msg)
303
309
  else:
304
310
  # save file
305
311
  common.write_yaml(transformed_obj, out_file, mime)
@@ -307,7 +313,9 @@ def build_finished(app, exception):
307
313
 
308
314
  # Write TOC, the toc should include at least 1
309
315
  if len(toc_yaml) == 0:
310
- raise RuntimeError("No documentation for this module.")
316
+ msg = "No documentation for this module."
317
+ py2docfx_logger.error(msg)
318
+ raise RuntimeError()
311
319
 
312
320
  toc_file = os.path.join(normalized_outdir, 'toc.yml')
313
321
  with open(toc_file, 'w') as writable:
@@ -3,9 +3,10 @@ import os
3
3
  import yaml as yml
4
4
  from functools import partial
5
5
  from common import remove_empty_values, parse_references, convert_member, convert_parameter, convert_types, get_constructor_and_variables, convert_variable
6
-
6
+ from logger import get_package_logger
7
7
 
8
8
  def convert_class(obj):
9
+ py2docfx_logger = get_package_logger(__name__)
9
10
  record = {}
10
11
  reference_mapping = {}
11
12
  old_class_object = {}
@@ -48,5 +49,6 @@ def convert_class(obj):
48
49
  new_class_object['methods'] = list(map(convert_member_partial, methods))
49
50
  new_class_object['attributes'] = list(map(convert_member_partial, attributes))
50
51
 
51
- print("class: " + new_class_object['uid']) # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
52
+ msg = "class: " + new_class_object['uid'] # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
53
+ py2docfx_logger.info(msg)
52
54
  return remove_empty_values(new_class_object)
@@ -1,12 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  from common import remove_empty_values, parse_references, get_constructor_and_variables, convert_variable
3
-
3
+ from logger import get_package_logger
4
4
 
5
5
  def convert_enum(obj):
6
6
  ''' Convert the Enum yaml object to a SDP style object.
7
7
 
8
8
  :param obj: The object is generated from the Enum yaml file
9
9
  '''
10
+ py2docfx_logger = get_package_logger(__name__)
10
11
  record = {}
11
12
  reference_mapping = {}
12
13
  old_enum_object = {}
@@ -43,7 +44,8 @@ def convert_enum(obj):
43
44
 
44
45
  new_enum_object['fields'] = list(map(convert_fields, fields))
45
46
 
46
- print("enum: " + new_enum_object['uid']) # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
47
+ msg = "enum: " + new_enum_object['uid'] # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
48
+ py2docfx_logger.info(msg)
47
49
  return remove_empty_values(new_enum_object)
48
50
 
49
51
 
@@ -3,9 +3,10 @@ import os
3
3
  import yaml as yml
4
4
  from functools import partial
5
5
  from common import remove_empty_values, parse_references, convert_member
6
-
6
+ from logger import get_package_logger
7
7
 
8
8
  def convert_module(obj, uid_type_mapping):
9
+ py2docfx_logger = get_package_logger(__name__)
9
10
  record = {}
10
11
  reference_mapping = {}
11
12
  old_object = {}
@@ -54,5 +55,6 @@ def convert_module(obj, uid_type_mapping):
54
55
  filter(lambda x: uid_type_mapping.get(x, None) == 'enum', children))
55
56
 
56
57
  toreturn = remove_empty_values(new_object)
57
- print("module: " + toreturn['uid']) # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
58
+ msg = "module: " + toreturn['uid'] # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
59
+ py2docfx_logger.info(msg)
58
60
  return toreturn
@@ -3,9 +3,10 @@ import os
3
3
  import yaml as yml
4
4
  from functools import partial
5
5
  from common import remove_empty_values, parse_references, convert_member
6
-
6
+ from logger import get_package_logger
7
7
 
8
8
  def convert_package(obj, uid_type_mapping):
9
+ py2docfx_logger = get_package_logger(__name__)
9
10
  record = {}
10
11
  reference_mapping = {}
11
12
  old_object = {}
@@ -49,5 +50,6 @@ def convert_package(obj, uid_type_mapping):
49
50
  filter(lambda x: uid_type_mapping.get(x, None) == 'enum', children))
50
51
 
51
52
  toreturn = remove_empty_values(new_object)
52
- print("package: " + toreturn['uid']) # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
53
+ msg = "package: " + toreturn['uid'] # CodeQL: [py/clear-text-logging-sensitive-data] There is no sensitive data in the print statement.
54
+ py2docfx_logger.info(msg)
53
55
  return toreturn
@@ -0,0 +1,141 @@
1
+ import os
2
+ import logging
3
+ import subprocess
4
+ import shutil
5
+
6
+ def get_log_level():
7
+ if os.environ.get('LOG_LEVEL') == 'WARNING':
8
+ return logging.WARNING
9
+ elif os.environ.get('LOG_LEVEL') == 'INFO':
10
+ return logging.INFO
11
+
12
+ return logging.ERROR
13
+
14
+ def check_log_dir_exists(log_dir_path):
15
+ if not os.path.exists(log_dir_path):
16
+ os.makedirs(log_dir_path)
17
+
18
+ def check_log_file_exists(log_file_path):
19
+ # create log file if it doesn't exist
20
+ if not os.path.exists(log_file_path):
21
+ with open(log_file_path, 'w') as f:
22
+ f.write('')
23
+
24
+ def setup_log_handlers(logger, log_file_name):
25
+ check_log_file_exists(log_file_name)
26
+ file_handler = logging.FileHandler(filename=log_file_name, mode='a')
27
+ file_handler.setFormatter(logging.Formatter('%(name)s - %(levelname)s - %(message)s'))
28
+
29
+ logger.addHandler(file_handler)
30
+
31
+ return logger
32
+
33
+ def get_logger(logger_name: str):
34
+ log_folder_path = os.path.join("logs")
35
+ file_name = os.path.join(log_folder_path, "log.txt")
36
+
37
+ file_logger = logging.getLogger(logger_name)
38
+ file_logger.setLevel(logging.INFO)
39
+ check_log_dir_exists(log_folder_path)
40
+ if file_logger.hasHandlers():
41
+ return file_logger
42
+
43
+ file_logger = setup_log_handlers(file_logger, file_name)
44
+
45
+ return file_logger
46
+
47
+ def get_package_logger(logger_name:str):
48
+ log_folder_path = os.path.join("logs", "package_logs")
49
+ package_name = os.environ.get('PROCESSING_PACKAGE_NAME')
50
+ file_name = os.path.join(log_folder_path, f"{package_name}.txt")
51
+
52
+ file_logger = logging.getLogger(logger_name)
53
+ file_logger.setLevel(logging.INFO)
54
+ check_log_dir_exists(log_folder_path)
55
+ if file_logger.hasHandlers():
56
+ return file_logger
57
+
58
+ file_logger = setup_log_handlers(file_logger, file_name)
59
+
60
+ return file_logger
61
+
62
+ def log_subprocess_ouput(subprocess_out: subprocess.CompletedProcess, logger: logging.Logger):
63
+ if subprocess_out.stdout:
64
+ logger.info(subprocess_out.stdout)
65
+ if subprocess_out.stderr:
66
+ msgs = subprocess_out.stderr.split('\n')
67
+ for msg in msgs:
68
+ if msg is None or msg == "":
69
+ continue
70
+ if "WARNING:" in msg:
71
+ logger.warning(msg)
72
+ elif "ERROR:" in msg:
73
+ logger.error(msg)
74
+ else:
75
+ logger.info(msg)
76
+ if subprocess_out.returncode != 0:
77
+ logger.error(f"Subprocess failed with return code {subprocess_out.returncode}")
78
+ raise RuntimeError()
79
+
80
+ def counts_errors_warnings(log_file_path):
81
+ error_count = 0
82
+ warning_count = 0
83
+ with open(log_file_path, 'r', encoding='utf-8') as f:
84
+ lines = f.readlines()
85
+ for line in lines:
86
+ if "- ERROR -" in line:
87
+ error_count += 1
88
+ elif "- WARNING -" in line:
89
+ warning_count += 1
90
+ return warning_count, error_count
91
+
92
+ def get_warning_error_count():
93
+ main_log_file_path = os.path.join("logs", "log.txt")
94
+ warning_count, error_count = counts_errors_warnings(main_log_file_path)
95
+
96
+ log_folder_path = os.path.join("logs", "package_logs")
97
+ for log_file in os.listdir(log_folder_path):
98
+ log_file_path = os.path.join(log_folder_path, log_file)
99
+ warnings, errors = counts_errors_warnings(log_file_path)
100
+ warning_count += warnings
101
+ error_count += errors
102
+
103
+ return warning_count, error_count
104
+
105
+ def parse_log(log_file_path):
106
+ # reads the log file and parse it into a list of dictionaries
107
+ # the dictionary has the keys: 'name', 'level', 'message'
108
+ log_list = []
109
+ with open(log_file_path, 'r', encoding='utf-8') as f:
110
+ lines = f.readlines()
111
+ for line in lines:
112
+ if "- ERROR -" in line:
113
+ level = logging.INFO
114
+ elif "- WARNING -" in line:
115
+ level = logging.WARNING
116
+ elif "- INFO -" in line:
117
+ level = logging.INFO
118
+ else:
119
+ # put everything to the previous message
120
+ log_list[-1]['message'] += line
121
+ continue
122
+ temp_info = line.split(" - ")
123
+ logger_name = temp_info[0]
124
+ message = temp_info[2]
125
+ log_list.append({'name': logger_name, 'level': level, 'message': message})
126
+ return log_list
127
+
128
+ def print_out_log_by_log_level(log_list, log_level):
129
+ for log in log_list:
130
+ if log['level'] >= log_level and log['message'] not in ['', '\n', '\r\n']:
131
+ print(log['message'])
132
+
133
+ def output_log_by_log_level():
134
+ log_level = get_log_level()
135
+ main_log_file_path = os.path.join("logs", "log.txt")
136
+ print_out_log_by_log_level(parse_log(main_log_file_path), log_level)
137
+
138
+ package_logs_folder = os.path.join("logs", "package_logs")
139
+ for log_file in os.listdir(package_logs_folder):
140
+ log_file_path = os.path.join(package_logs_folder, log_file)
141
+ print_out_log_by_log_level(parse_log(log_file_path), log_level)
@@ -11,6 +11,7 @@ import re
11
11
  from utils import transform_string
12
12
  from enum import EnumMeta
13
13
  from importlib import import_module
14
+ from logger import get_package_logger
14
15
 
15
16
  PACKAGE = 'package'
16
17
  METHOD = 'method'
@@ -181,7 +182,7 @@ def _create_datam(app, cls, module, name, _type, obj, lines=None):
181
182
  """
182
183
  Build the data structure for an autodoc class
183
184
  """
184
-
185
+ py2docfx_logger = get_package_logger(__name__)
185
186
  if lines is None:
186
187
  lines = []
187
188
  short_name = name.split('.')[-1]
@@ -204,7 +205,8 @@ def _create_datam(app, cls, module, name, _type, obj, lines=None):
204
205
  args = removePositonalOnlyFromArgs(args, positional_only_params)
205
206
 
206
207
  except Exception as e:
207
- print("Can't get argspec for {}: {}. Exception: {}".format(type(obj), name, e))
208
+ msg = "Can't get argspec for {}: {}. Exception: {}".format(type(obj), name, e)
209
+ py2docfx_logger.warning(msg)
208
210
 
209
211
  datam = {
210
212
  'module': module if module else None,
@@ -388,7 +390,7 @@ def process_docstring(app, _type, name, obj, options, lines):
388
390
  This function takes the docstring and indexes it into memory.
389
391
  """
390
392
  # Use exception as class
391
-
393
+ py2docfx_logger = get_package_logger(__name__)
392
394
  def check_convert_package_type(obj, _type):
393
395
  if _type == MODULE:
394
396
  filename = getattr(obj, '__file__', None)
@@ -409,7 +411,7 @@ def process_docstring(app, _type, name, obj, options, lines):
409
411
  cls, module = _get_cls_module(_type, name)
410
412
 
411
413
  if _type != PACKAGE and not module:
412
- print('Unknown Type: %s' % _type)
414
+ py2docfx_logger.warning('Unknown Type: %s' % _type)
413
415
  return None
414
416
 
415
417
  if app.config.__contains__('autoclass_content') and app.config.autoclass_content.lower() == 'both':
@@ -11,10 +11,10 @@ import return_type_utils
11
11
  from docutils import nodes
12
12
  from sphinx import addnodes
13
13
  from sphinx.addnodes import desc_signature,desc_content
14
- from sphinx.util import logging
15
14
  from sphinx.util.docfields import _is_single_paragraph
16
15
  from collections import OrderedDict
17
16
  from nodes import remarks
17
+ from logger import get_package_logger
18
18
 
19
19
  TYPE_SEP_PATTERN = '(\[|\]|, |\(|\))'
20
20
  PARAMETER_NAME = "[*][*](.*?)[*][*]"
@@ -26,10 +26,9 @@ ATTRIBUTE_TYPE = 'attribute'
26
26
  types_contain_constructor = {CLASS_TYPE, EXCEPTION_TYPE}
27
27
  types_contain_attributes = {CLASS_TYPE, EXCEPTION_TYPE}
28
28
 
29
- logger = logging.getLogger(__name__)
30
-
31
29
  def translator(app, docname, doctree):
32
30
 
31
+ py2docfx_logger = get_package_logger(__name__)
33
32
  transform_node = app.docfx_transform_node
34
33
 
35
34
  class_obj_cache = app.env.domains['py'].objects
@@ -58,16 +57,15 @@ def translator(app, docname, doctree):
58
57
  def _get_uid_and_type_from_desc(node):
59
58
  assert node.tagname == 'desc'
60
59
  if node.attributes['domain'] != 'py':
61
- print(
62
- 'Skipping Domain Object (%s)' % node.attributes['domain']
63
- )
60
+ msg = str('Skipping Domain Object (%s)' % node.attributes['domain'])
61
+ py2docfx_logger.info(msg)
64
62
  return None, None
65
63
 
66
64
  try:
67
65
  module = node[0].attributes['module']
68
66
  full_name = node[0].attributes['fullname']
69
67
  except KeyError as e:
70
- logger.error("There maybe some syntax error in docstring near: " + node.astext())
68
+ py2docfx_logger.error("There maybe some syntax error in docstring near: " + node.astext())
71
69
  raise e
72
70
 
73
71
  uid = '{module}.{full_name}'.format(module=module, full_name=full_name)
@@ -32,6 +32,7 @@ from sphinx.locale import admonitionlabels
32
32
 
33
33
  from nodes import remarks
34
34
  import write_utils
35
+ from logger import get_package_logger
35
36
 
36
37
  class bcolors:
37
38
  HEADER = '\033[95m'
@@ -601,8 +602,9 @@ class MarkdownTranslator(nodes.NodeVisitor):
601
602
  image_name = '/'.join(node.attributes['uri'].split(
602
603
  '/')[node.attributes['uri'].split('/').index('_static')-1:])
603
604
  except ValueError as e:
604
- print("Image not found where expected {}".format(
605
- node.attributes['uri']))
605
+ msg = "Image not found where expected {}".format(
606
+ node.attributes['uri'])
607
+ py2docfx_logger.warning(msg)
606
608
  raise nodes.SkipNode
607
609
  image_name = ''.join(image_name.split())
608
610
  self.new_state(0)
@@ -1083,8 +1085,10 @@ class MarkdownTranslator(nodes.NodeVisitor):
1083
1085
  self.add_text('<<')
1084
1086
 
1085
1087
  def visit_system_message(self, node):
1086
- print(bcolors.WARNING + "System message warnings: %s" %
1088
+ py2docfx_logger = get_package_logger(__name__)
1089
+ msg = str(bcolors.WARNING + "System message warnings: %s" %
1087
1090
  self.replace_special_unicode(node.astext()) + bcolors.ENDC)
1091
+ py2docfx_logger.warning(msg)
1088
1092
  raise nodes.SkipNode
1089
1093
 
1090
1094
  def visit_comment(self, node):
@@ -1102,12 +1106,14 @@ class MarkdownTranslator(nodes.NodeVisitor):
1102
1106
  raise nodes.SkipNode
1103
1107
 
1104
1108
  def visit_math(self, node):
1105
- print(bcolors.WARNING +
1109
+ py2docfx_logger = get_package_logger(__name__)
1110
+ msg = str(bcolors.WARNING +
1106
1111
  ('using "math" markup without a Sphinx math extension '
1107
1112
  'active, please use one of the math extensions '
1108
1113
  'described at http://sphinx-doc.org/ext/math.html. Source_path is: {}; Line is: {}').format(
1109
1114
  node.source if node.source else node.parent.source,
1110
1115
  node.line if node.line else node.parent.line))
1116
+ py2docfx_logger.warning(msg)
1111
1117
  raise nodes.SkipNode
1112
1118
 
1113
1119
  visit_math_block = visit_math
@@ -7,7 +7,6 @@
7
7
  """
8
8
  Simaple YamlBuilder for parsing .yml output
9
9
  """
10
-
11
10
  from io import open
12
11
  from os import path
13
12
 
@@ -91,11 +91,11 @@ class Distribution(setuptools.dist.Distribution):
91
91
  for the duration of this context.
92
92
  """
93
93
  orig = distutils.core.Distribution
94
- distutils.core.Distribution = cls
94
+ distutils.core.Distribution = cls # type: ignore[misc] # monkeypatching
95
95
  try:
96
96
  yield
97
97
  finally:
98
- distutils.core.Distribution = orig
98
+ distutils.core.Distribution = orig # type: ignore[misc] # monkeypatching
99
99
 
100
100
 
101
101
  @contextlib.contextmanager
@@ -277,7 +277,7 @@ class bdist_egg(Command):
277
277
  log.warn("zip_safe flag not set; analyzing archive contents...")
278
278
  return analyze_egg(self.bdist_dir, self.stubs)
279
279
 
280
- def gen_header(self) -> str:
280
+ def gen_header(self) -> Literal["w"]:
281
281
  return 'w'
282
282
 
283
283
  def copy_metadata_to(self, target_dir) -> None:
@@ -14,14 +14,12 @@ import sys
14
14
  import sysconfig
15
15
  import warnings
16
16
  from collections.abc import Iterable, Sequence
17
- from email.generator import BytesGenerator, Generator
18
- from email.policy import EmailPolicy
17
+ from email.generator import BytesGenerator
19
18
  from glob import iglob
20
19
  from typing import Literal, cast
21
20
  from zipfile import ZIP_DEFLATED, ZIP_STORED
22
21
 
23
22
  from packaging import tags, version as _packaging_version
24
- from wheel.metadata import pkginfo_to_metadata
25
23
  from wheel.wheelfile import WheelFile
26
24
 
27
25
  from .. import Command, __version__, _shutil
@@ -220,7 +218,7 @@ class bdist_wheel(Command):
220
218
 
221
219
  def initialize_options(self) -> None:
222
220
  self.bdist_dir: str | None = None
223
- self.data_dir: str | None = None
221
+ self.data_dir = ""
224
222
  self.plat_name: str | None = None
225
223
  self.plat_tag: str | None = None
226
224
  self.format = "zip"
@@ -569,42 +567,30 @@ class bdist_wheel(Command):
569
567
 
570
568
  raise ValueError(err)
571
569
 
572
- if os.path.isfile(egginfo_path):
573
- # .egg-info is a single file
574
- pkg_info = pkginfo_to_metadata(egginfo_path, egginfo_path)
575
- os.mkdir(distinfo_path)
576
- else:
577
- # .egg-info is a directory
578
- pkginfo_path = os.path.join(egginfo_path, "PKG-INFO")
579
- pkg_info = pkginfo_to_metadata(egginfo_path, pkginfo_path)
580
-
581
- # ignore common egg metadata that is useless to wheel
582
- shutil.copytree(
583
- egginfo_path,
584
- distinfo_path,
585
- ignore=lambda x, y: {
586
- "PKG-INFO",
587
- "requires.txt",
588
- "SOURCES.txt",
589
- "not-zip-safe",
590
- },
591
- )
592
-
593
- # delete dependency_links if it is only whitespace
594
- dependency_links_path = os.path.join(distinfo_path, "dependency_links.txt")
595
- with open(dependency_links_path, encoding="utf-8") as dependency_links_file:
596
- dependency_links = dependency_links_file.read().strip()
597
- if not dependency_links:
598
- adios(dependency_links_path)
599
-
600
- pkg_info_path = os.path.join(distinfo_path, "METADATA")
601
- serialization_policy = EmailPolicy(
602
- utf8=True,
603
- mangle_from_=False,
604
- max_line_length=0,
570
+ # .egg-info is a directory
571
+ pkginfo_path = os.path.join(egginfo_path, "PKG-INFO")
572
+
573
+ # ignore common egg metadata that is useless to wheel
574
+ shutil.copytree(
575
+ egginfo_path,
576
+ distinfo_path,
577
+ ignore=lambda x, y: {
578
+ "PKG-INFO",
579
+ "requires.txt",
580
+ "SOURCES.txt",
581
+ "not-zip-safe",
582
+ },
605
583
  )
606
- with open(pkg_info_path, "w", encoding="utf-8") as out:
607
- Generator(out, policy=serialization_policy).flatten(pkg_info)
584
+
585
+ # delete dependency_links if it is only whitespace
586
+ dependency_links_path = os.path.join(distinfo_path, "dependency_links.txt")
587
+ with open(dependency_links_path, encoding="utf-8") as dependency_links_file:
588
+ dependency_links = dependency_links_file.read().strip()
589
+ if not dependency_links:
590
+ adios(dependency_links_path)
591
+
592
+ metadata_path = os.path.join(distinfo_path, "METADATA")
593
+ shutil.copy(pkginfo_path, metadata_path)
608
594
 
609
595
  for license_path in self.license_paths:
610
596
  filename = os.path.basename(license_path)