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.
- py2docfx/__main__.py +72 -23
- py2docfx/convert_prepare/conf_templates/conf.py_t +1 -1
- py2docfx/convert_prepare/constants.py +2 -1
- py2docfx/convert_prepare/environment.py +34 -13
- py2docfx/convert_prepare/generate_document.py +12 -5
- py2docfx/convert_prepare/get_source.py +5 -1
- py2docfx/convert_prepare/git.py +24 -20
- py2docfx/convert_prepare/package_info.py +15 -9
- py2docfx/convert_prepare/pip_utils.py +33 -8
- py2docfx/convert_prepare/post_process/merge_toc.py +5 -1
- py2docfx/convert_prepare/sphinx_caller.py +31 -14
- py2docfx/docfx_yaml/build_finished.py +11 -3
- py2docfx/docfx_yaml/convert_class.py +4 -2
- py2docfx/docfx_yaml/convert_enum.py +4 -2
- py2docfx/docfx_yaml/convert_module.py +4 -2
- py2docfx/docfx_yaml/convert_package.py +4 -2
- py2docfx/docfx_yaml/logger.py +141 -0
- py2docfx/docfx_yaml/process_doctree.py +6 -4
- py2docfx/docfx_yaml/translator.py +5 -7
- py2docfx/docfx_yaml/writer.py +10 -4
- py2docfx/docfx_yaml/yaml_builder.py +0 -1
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/build_meta.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/bdist_egg.py +1 -1
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/bdist_wheel.py +25 -39
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/build_ext.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/build_py.py +9 -14
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/easy_install.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/editable_wheel.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/egg_info.py +3 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/install_egg_info.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/saveopts.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/sdist.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/setopt.py +1 -1
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/config/pyprojecttoml.py +0 -13
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/dist.py +3 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/monkey.py +3 -3
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/msvc.py +11 -11
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/tests/config/test_pyprojecttoml.py +0 -7
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/tests/test_core_metadata.py +168 -72
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/unicode_utils.py +3 -3
- py2docfx/venv/basevenv/Lib/site-packages/wheel/__init__.py +1 -1
- py2docfx/venv/basevenv/Lib/site-packages/wheel/cli/convert.py +1 -2
- py2docfx/venv/venv1/Lib/site-packages/jwt/__init__.py +3 -2
- py2docfx/venv/venv1/Lib/site-packages/jwt/algorithms.py +31 -16
- py2docfx/venv/venv1/Lib/site-packages/jwt/api_jws.py +19 -8
- py2docfx/venv/venv1/Lib/site-packages/jwt/api_jwt.py +75 -19
- py2docfx/venv/venv1/Lib/site-packages/jwt/exceptions.py +8 -0
- py2docfx/venv/venv1/Lib/site-packages/jwt/help.py +4 -1
- py2docfx/venv/venv1/Lib/site-packages/jwt/jwks_client.py +4 -2
- py2docfx/venv/venv1/Lib/site-packages/jwt/utils.py +7 -10
- py2docfx/venv/venv1/Lib/site-packages/msal/application.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/msal/managed_identity.py +5 -3
- py2docfx/venv/venv1/Lib/site-packages/setuptools/build_meta.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/bdist_egg.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/bdist_wheel.py +25 -39
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/build_ext.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/build_py.py +9 -14
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/easy_install.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/editable_wheel.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/egg_info.py +3 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/install_egg_info.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/saveopts.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/sdist.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/setopt.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/setuptools/config/pyprojecttoml.py +0 -13
- py2docfx/venv/venv1/Lib/site-packages/setuptools/dist.py +3 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/monkey.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/setuptools/msvc.py +11 -11
- py2docfx/venv/venv1/Lib/site-packages/setuptools/tests/config/test_pyprojecttoml.py +0 -7
- py2docfx/venv/venv1/Lib/site-packages/setuptools/tests/test_core_metadata.py +168 -72
- py2docfx/venv/venv1/Lib/site-packages/setuptools/unicode_utils.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/wheel/__init__.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/wheel/cli/convert.py +1 -2
- {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/METADATA +1 -1
- {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/RECORD +78 -77
- {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/WHEEL +1 -1
- /py2docfx/convert_prepare/conf_templates/{master_doc.rst_t → root_doc.rst_t} +0 -0
- {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
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
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
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
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
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
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
|
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:
|
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:`
|
71
|
+
:meth:`RawConfigParser.read` method.
|
72
72
|
|
73
73
|
This method may call ``cfg.clear()``.
|
74
74
|
"""
|
@@ -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.
|
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
|