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
@@ -1,16 +1,28 @@
1
+ from __future__ import annotations
2
+
1
3
  import functools
2
4
  import importlib
3
5
  import io
4
6
  from email import message_from_string
7
+ from email.generator import Generator
8
+ from email.message import Message
9
+ from email.parser import Parser
10
+ from email.policy import EmailPolicy
11
+ from pathlib import Path
12
+ from unittest.mock import Mock
5
13
 
6
14
  import pytest
7
15
  from packaging.metadata import Metadata
16
+ from packaging.requirements import Requirement
8
17
 
9
18
  from setuptools import _reqs, sic
10
19
  from setuptools._core_metadata import rfc822_escape, rfc822_unescape
11
20
  from setuptools.command.egg_info import egg_info, write_requirements
21
+ from setuptools.config import expand, setupcfg
12
22
  from setuptools.dist import Distribution
13
23
 
24
+ from .config.downloads import retrieve_file, urls_from_file
25
+
14
26
  EXAMPLE_BASE_INFO = dict(
15
27
  name="package",
16
28
  version="0.0.1",
@@ -303,84 +315,168 @@ def test_maintainer_author(name, attrs, tmpdir):
303
315
  assert line in pkg_lines_set
304
316
 
305
317
 
306
- def test_parity_with_metadata_from_pypa_wheel(tmp_path):
307
- attrs = dict(
308
- **EXAMPLE_BASE_INFO,
309
- # Example with complex requirement definition
310
- python_requires=">=3.8",
311
- install_requires="""
312
- packaging==23.2
313
- more-itertools==8.8.0; extra == "other"
314
- jaraco.text==3.7.0
315
- importlib-resources==5.10.2; python_version<"3.8"
316
- importlib-metadata==6.0.0 ; python_version<"3.8"
317
- colorama>=0.4.4; sys_platform == "win32"
318
- """,
319
- extras_require={
320
- "testing": """
321
- pytest >= 6
322
- pytest-checkdocs >= 2.4
323
- tomli ; \\
324
- # Using stdlib when possible
325
- python_version < "3.11"
326
- ini2toml[lite]>=0.9
327
- """,
328
- "other": [],
329
- },
318
+ class TestParityWithMetadataFromPyPaWheel:
319
+ def base_example(self):
320
+ attrs = dict(
321
+ **EXAMPLE_BASE_INFO,
322
+ # Example with complex requirement definition
323
+ python_requires=">=3.8",
324
+ install_requires="""
325
+ packaging==23.2
326
+ more-itertools==8.8.0; extra == "other"
327
+ jaraco.text==3.7.0
328
+ importlib-resources==5.10.2; python_version<"3.8"
329
+ importlib-metadata==6.0.0 ; python_version<"3.8"
330
+ colorama>=0.4.4; sys_platform == "win32"
331
+ """,
332
+ extras_require={
333
+ "testing": """
334
+ pytest >= 6
335
+ pytest-checkdocs >= 2.4
336
+ tomli ; \\
337
+ # Using stdlib when possible
338
+ python_version < "3.11"
339
+ ini2toml[lite]>=0.9
340
+ """,
341
+ "other": [],
342
+ },
343
+ )
344
+ # Generate a PKG-INFO file using setuptools
345
+ return Distribution(attrs)
346
+
347
+ def test_requires_dist(self, tmp_path):
348
+ dist = self.base_example()
349
+ pkg_info = _get_pkginfo(dist)
350
+ assert _valid_metadata(pkg_info)
351
+
352
+ # Ensure Requires-Dist is present
353
+ expected = [
354
+ 'Metadata-Version:',
355
+ 'Requires-Python: >=3.8',
356
+ 'Provides-Extra: other',
357
+ 'Provides-Extra: testing',
358
+ 'Requires-Dist: tomli; python_version < "3.11" and extra == "testing"',
359
+ 'Requires-Dist: more-itertools==8.8.0; extra == "other"',
360
+ 'Requires-Dist: ini2toml[lite]>=0.9; extra == "testing"',
361
+ ]
362
+ for line in expected:
363
+ assert line in pkg_info
364
+
365
+ HERE = Path(__file__).parent
366
+ EXAMPLES_FILE = HERE / "config/setupcfg_examples.txt"
367
+
368
+ @pytest.fixture(params=[None, *urls_from_file(EXAMPLES_FILE)])
369
+ def dist(self, request, monkeypatch, tmp_path):
370
+ """Example of distribution with arbitrary configuration"""
371
+ monkeypatch.chdir(tmp_path)
372
+ monkeypatch.setattr(expand, "read_attr", Mock(return_value="0.42"))
373
+ monkeypatch.setattr(expand, "read_files", Mock(return_value="hello world"))
374
+ if request.param is None:
375
+ yield self.base_example()
376
+ else:
377
+ # Real-world usage
378
+ config = retrieve_file(request.param)
379
+ yield setupcfg.apply_configuration(Distribution({}), config)
380
+
381
+ @pytest.mark.uses_network
382
+ def test_equivalent_output(self, tmp_path, dist):
383
+ """Ensure output from setuptools is equivalent to the one from `pypa/wheel`"""
384
+ # Generate a METADATA file using pypa/wheel for comparison
385
+ wheel_metadata = importlib.import_module("wheel.metadata")
386
+ pkginfo_to_metadata = getattr(wheel_metadata, "pkginfo_to_metadata", None)
387
+
388
+ if pkginfo_to_metadata is None: # pragma: nocover
389
+ pytest.xfail(
390
+ "wheel.metadata.pkginfo_to_metadata is undefined, "
391
+ "(this is likely to be caused by API changes in pypa/wheel"
392
+ )
393
+
394
+ # Generate an simplified "egg-info" dir for pypa/wheel to convert
395
+ pkg_info = _get_pkginfo(dist)
396
+ egg_info_dir = tmp_path / "pkg.egg-info"
397
+ egg_info_dir.mkdir(parents=True)
398
+ (egg_info_dir / "PKG-INFO").write_text(pkg_info, encoding="utf-8")
399
+ write_requirements(egg_info(dist), egg_info_dir, egg_info_dir / "requires.txt")
400
+
401
+ # Get pypa/wheel generated METADATA but normalize requirements formatting
402
+ metadata_msg = pkginfo_to_metadata(egg_info_dir, egg_info_dir / "PKG-INFO")
403
+ metadata_str = _normalize_metadata(metadata_msg)
404
+ pkg_info_msg = message_from_string(pkg_info)
405
+ pkg_info_str = _normalize_metadata(pkg_info_msg)
406
+
407
+ # Compare setuptools PKG-INFO x pypa/wheel METADATA
408
+ assert metadata_str == pkg_info_str
409
+
410
+ # Make sure it parses/serializes well in pypa/wheel
411
+ _assert_roundtrip_message(pkg_info)
412
+
413
+
414
+ def _assert_roundtrip_message(metadata: str) -> None:
415
+ """Emulate the way wheel.bdist_wheel parses and regenerates the message,
416
+ then ensures the metadata generated by setuptools is compatible.
417
+ """
418
+ with io.StringIO(metadata) as buffer:
419
+ msg = Parser().parse(buffer)
420
+
421
+ serialization_policy = EmailPolicy(
422
+ utf8=True,
423
+ mangle_from_=False,
424
+ max_line_length=0,
330
425
  )
331
- # Generate a PKG-INFO file using setuptools
332
- dist = Distribution(attrs)
333
- with io.StringIO() as fp:
334
- dist.metadata.write_pkg_file(fp)
335
- pkg_info = fp.getvalue()
426
+ with io.BytesIO() as buffer:
427
+ out = io.TextIOWrapper(buffer, encoding="utf-8")
428
+ Generator(out, policy=serialization_policy).flatten(msg)
429
+ out.flush()
430
+ regenerated = buffer.getvalue()
431
+
432
+ raw_metadata = bytes(metadata, "utf-8")
433
+ # Normalise newlines to avoid test errors on Windows:
434
+ raw_metadata = b"\n".join(raw_metadata.splitlines())
435
+ regenerated = b"\n".join(regenerated.splitlines())
436
+ assert regenerated == raw_metadata
437
+
438
+
439
+ def _normalize_metadata(msg: Message) -> str:
440
+ """Allow equivalent metadata to be compared directly"""
441
+ # The main challenge regards the requirements and extras.
442
+ # Both setuptools and wheel already apply some level of normalization
443
+ # but they differ regarding which character is chosen, according to the
444
+ # following spec it should be "-":
445
+ # https://packaging.python.org/en/latest/specifications/name-normalization/
446
+
447
+ # Related issues:
448
+ # https://github.com/pypa/packaging/issues/845
449
+ # https://github.com/pypa/packaging/issues/644#issuecomment-2429813968
450
+
451
+ extras = {x.replace("_", "-"): x for x in msg.get_all("Provides-Extra", [])}
452
+ reqs = [
453
+ _normalize_req(req, extras)
454
+ for req in _reqs.parse(msg.get_all("Requires-Dist", []))
455
+ ]
456
+ del msg["Requires-Dist"]
457
+ del msg["Provides-Extra"]
336
458
 
337
- assert _valid_metadata(pkg_info)
459
+ # Ensure consistent ord
460
+ for req in sorted(reqs):
461
+ msg["Requires-Dist"] = req
462
+ for extra in sorted(extras):
463
+ msg["Provides-Extra"] = extra
338
464
 
339
- # Ensure Requires-Dist is present
340
- expected = [
341
- 'Metadata-Version:',
342
- 'Requires-Python: >=3.8',
343
- 'Provides-Extra: other',
344
- 'Provides-Extra: testing',
345
- 'Requires-Dist: tomli; python_version < "3.11" and extra == "testing"',
346
- 'Requires-Dist: more-itertools==8.8.0; extra == "other"',
347
- 'Requires-Dist: ini2toml[lite]>=0.9; extra == "testing"',
348
- ]
349
- for line in expected:
350
- assert line in pkg_info
465
+ return msg.as_string()
351
466
 
352
- # Generate a METADATA file using pypa/wheel for comparison
353
- wheel_metadata = importlib.import_module("wheel.metadata")
354
- pkginfo_to_metadata = getattr(wheel_metadata, "pkginfo_to_metadata", None)
355
467
 
356
- if pkginfo_to_metadata is None:
357
- pytest.xfail(
358
- "wheel.metadata.pkginfo_to_metadata is undefined, "
359
- "(this is likely to be caused by API changes in pypa/wheel"
360
- )
468
+ def _normalize_req(req: Requirement, extras: dict[str, str]) -> str:
469
+ """Allow equivalent requirement objects to be compared directly"""
470
+ as_str = str(req).replace(req.name, req.name.replace("_", "-"))
471
+ for norm, orig in extras.items():
472
+ as_str = as_str.replace(orig, norm)
473
+ return as_str
361
474
 
362
- # Generate an simplified "egg-info" dir for pypa/wheel to convert
363
- egg_info_dir = tmp_path / "pkg.egg-info"
364
- egg_info_dir.mkdir(parents=True)
365
- (egg_info_dir / "PKG-INFO").write_text(pkg_info, encoding="utf-8")
366
- write_requirements(egg_info(dist), egg_info_dir, egg_info_dir / "requires.txt")
367
-
368
- # Get pypa/wheel generated METADATA but normalize requirements formatting
369
- metadata_msg = pkginfo_to_metadata(egg_info_dir, egg_info_dir / "PKG-INFO")
370
- metadata_deps = set(_reqs.parse(metadata_msg.get_all("Requires-Dist")))
371
- metadata_extras = set(metadata_msg.get_all("Provides-Extra"))
372
- del metadata_msg["Requires-Dist"]
373
- del metadata_msg["Provides-Extra"]
374
- pkg_info_msg = message_from_string(pkg_info)
375
- pkg_info_deps = set(_reqs.parse(pkg_info_msg.get_all("Requires-Dist")))
376
- pkg_info_extras = set(pkg_info_msg.get_all("Provides-Extra"))
377
- del pkg_info_msg["Requires-Dist"]
378
- del pkg_info_msg["Provides-Extra"]
379
-
380
- # Compare setuptools PKG-INFO x pypa/wheel METADATA
381
- assert metadata_msg.as_string() == pkg_info_msg.as_string()
382
- assert metadata_deps == pkg_info_deps
383
- assert metadata_extras == pkg_info_extras
475
+
476
+ def _get_pkginfo(dist: Distribution):
477
+ with io.StringIO() as fp:
478
+ dist.metadata.write_pkg_file(fp)
479
+ return fp.getvalue()
384
480
 
385
481
 
386
482
  def _valid_metadata(text: str) -> bool:
@@ -1,6 +1,6 @@
1
1
  import sys
2
2
  import unicodedata
3
- from configparser import ConfigParser
3
+ from configparser import RawConfigParser
4
4
 
5
5
  from .compat import py39
6
6
  from .warnings import SetuptoolsDeprecationWarning
@@ -65,10 +65,10 @@ def _read_utf8_with_fallback(file: str, fallback_encoding=py39.LOCALE_ENCODING)
65
65
 
66
66
 
67
67
  def _cfg_read_utf8_with_fallback(
68
- cfg: ConfigParser, file: str, fallback_encoding=py39.LOCALE_ENCODING
68
+ cfg: RawConfigParser, file: str, fallback_encoding=py39.LOCALE_ENCODING
69
69
  ) -> None:
70
70
  """Same idea as :func:`_read_utf8_with_fallback`, but for the
71
- :meth:`ConfigParser.read` method.
71
+ :meth:`RawConfigParser.read` method.
72
72
 
73
73
  This method may call ``cfg.clear()``.
74
74
  """
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.45.0"
3
+ __version__ = "0.45.1"
@@ -122,8 +122,8 @@ class EggFileSource(ConvertSource):
122
122
  self.version = match.group("ver")
123
123
  if pyver := match.group("pyver"):
124
124
  self.pyver = pyver.replace(".", "")
125
- self.abi = self.pyver.replace("py", "cp")
126
125
  if arch := match.group("arch"):
126
+ self.abi = self.pyver.replace("py", "cp")
127
127
  self.platform = normalize(arch)
128
128
 
129
129
  self.metadata = Message()
@@ -225,7 +225,6 @@ class WininstFileSource(ConvertSource):
225
225
  self.platform = normalize(match.group("platform"))
226
226
  if pyver := match.group("pyver"):
227
227
  self.pyver = pyver.replace(".", "")
228
- self.abi = pyver.replace("py", "cp")
229
228
 
230
229
  # Look for an .egg-info directory and any .pyd files for more precise info
231
230
  egg_info_found = pyd_found = False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: py2docfx
3
- Version: 0.1.9.dev1917798
3
+ Version: 0.1.9.dev1927042
4
4
  Summary: A package built based on Sphinx which download source code package and generate yaml files supported by docfx.
5
5
  Author: Microsoft Corporation
6
6
  License: MIT License