py2docfx 0.1.15.dev2038852__py3-none-any.whl → 0.1.16__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 (35) hide show
  1. py2docfx/docfx_yaml/process_doctree.py +21 -34
  2. py2docfx/docfx_yaml/tests/test_method_arguments.py +1 -7
  3. py2docfx/docfx_yaml/tests/test_process_doctree.py +120 -0
  4. py2docfx/venv/basevenv/Lib/site-packages/setuptools/_distutils/_msvccompiler.py +11 -0
  5. py2docfx/venv/basevenv/Lib/site-packages/setuptools/_distutils/command/__init__.py +8 -27
  6. py2docfx/venv/basevenv/Lib/site-packages/setuptools/config/_apply_pyprojecttoml.py +3 -2
  7. py2docfx/venv/basevenv/Lib/site-packages/setuptools/dist.py +53 -42
  8. py2docfx/venv/basevenv/Lib/site-packages/setuptools/tests/config/test_setupcfg.py +42 -29
  9. py2docfx/venv/basevenv/Lib/site-packages/setuptools/tests/integration/test_pip_install_sdist.py +1 -1
  10. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/__init__.py +1 -1
  11. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/any_pb2.py +2 -2
  12. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/api_pb2.py +2 -2
  13. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/compiler/plugin_pb2.py +2 -2
  14. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/descriptor_pb2.py +2 -2
  15. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/duration_pb2.py +2 -2
  16. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/empty_pb2.py +2 -2
  17. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/field_mask_pb2.py +2 -2
  18. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/runtime_version.py +1 -1
  19. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/source_context_pb2.py +2 -2
  20. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/struct_pb2.py +2 -2
  21. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/timestamp_pb2.py +2 -2
  22. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/type_pb2.py +2 -2
  23. py2docfx/venv/venv1/Lib/site-packages/google/protobuf/wrappers_pb2.py +2 -2
  24. py2docfx/venv/venv1/Lib/site-packages/pyasn1_modules/__init__.py +1 -1
  25. py2docfx/venv/venv1/Lib/site-packages/setuptools/_distutils/_msvccompiler.py +11 -0
  26. py2docfx/venv/venv1/Lib/site-packages/setuptools/_distutils/command/__init__.py +8 -27
  27. py2docfx/venv/venv1/Lib/site-packages/setuptools/config/_apply_pyprojecttoml.py +3 -2
  28. py2docfx/venv/venv1/Lib/site-packages/setuptools/dist.py +53 -42
  29. py2docfx/venv/venv1/Lib/site-packages/setuptools/tests/config/test_setupcfg.py +42 -29
  30. py2docfx/venv/venv1/Lib/site-packages/setuptools/tests/integration/test_pip_install_sdist.py +1 -1
  31. py2docfx/venv/venv1/Lib/site-packages/typing_extensions.py +999 -74
  32. {py2docfx-0.1.15.dev2038852.dist-info → py2docfx-0.1.16.dist-info}/METADATA +1 -1
  33. {py2docfx-0.1.15.dev2038852.dist-info → py2docfx-0.1.16.dist-info}/RECORD +35 -34
  34. {py2docfx-0.1.15.dev2038852.dist-info → py2docfx-0.1.16.dist-info}/WHEEL +0 -0
  35. {py2docfx-0.1.15.dev2038852.dist-info → py2docfx-0.1.16.dist-info}/top_level.txt +0 -0
@@ -111,38 +111,27 @@ def _resolve_reference_in_module_summary(lines):
111
111
  new_lines.append(new_line)
112
112
  return new_lines
113
113
 
114
- def getParameterArgs(argspec):
114
+ def getParameterArgs(signature):
115
115
  args = []
116
- for arg in argspec.args:
117
- args.append({'id': arg})
118
- if argspec.defaults:
119
- for count, default in enumerate(argspec.defaults):
120
- cut_count = len(argspec.defaults)
121
- # Only add defaultValue when str(default) doesn't contain object address string
122
- # (object at 0x)(lambda at 0x)(function *** at 0x)
123
- # inspect.getargspec method will return wrong defaults which contain object address for some default values, like sys.stdout
124
- # Match the defaults with the count
125
- if ' at 0x' not in str(default):
126
- args[len(args) - cut_count +
127
- count]['defaultValue'] = str(default)
128
- else:
129
- args[len(args) - cut_count +
130
- count]['isRequired'] = False
116
+ for param in signature.parameters.values():
117
+ if param.kind in [param.POSITIONAL_OR_KEYWORD, param.POSITIONAL_ONLY]:
118
+ arg = {'id': param.name}
119
+ if param.default is not param.empty:
120
+ if ' at 0x' not in str(param.default):
121
+ arg['defaultValue'] = str(param.default)
122
+ else:
123
+ arg['isRequired'] = False
124
+ args.append(arg)
131
125
  return args
132
126
 
133
- def getKeywordOnlyParameters(argspec):
127
+ def getKeywordOnlyParameters(signature):
134
128
  keyword_only_args = []
135
- # check if there is keyword only args
136
- if argspec.kwonlyargs:
137
- count = 0
138
- for arg in argspec.kwonlyargs:
139
- keyword_only_args.append({'id': arg})
140
- # try get the default value for keyword only args
141
- if argspec.kwonlydefaults:
142
- kwarg_default = argspec.kwonlydefaults.get(arg, None)
143
- if kwarg_default:
144
- keyword_only_args[count]['defaultValue'] = str(kwarg_default)
145
- count += 1
129
+ for param in signature.parameters.values():
130
+ if param.kind == param.KEYWORD_ONLY:
131
+ kwarg = {'id': param.name}
132
+ if param.default is not param.empty:
133
+ kwarg['defaultValue'] = str(param.default)
134
+ keyword_only_args.append(kwarg)
146
135
  return keyword_only_args
147
136
 
148
137
  def getpositionalOnlyParameters(signature):
@@ -193,13 +182,10 @@ def _create_datam(app, cls, module, name, _type, obj, lines=None):
193
182
  if _type in [CLASS, METHOD, FUNCTION]:
194
183
  if not (_type == CLASS and isinstance(type(obj).__call__, type(EnumMeta.__call__))):
195
184
  signature = inspect.signature(obj)
196
- argspec = inspect.getfullargspec(obj)
197
-
198
- args = getParameterArgs(argspec)
199
- keyword_only_args = getKeywordOnlyParameters(argspec)
185
+ args = getParameterArgs(signature)
186
+ keyword_only_args = getKeywordOnlyParameters(signature)
200
187
  positional_only_params = getpositionalOnlyParameters(signature)
201
-
202
- # The args will contian both regular args and positional only params
188
+ # The args will contain both regular args and positional only params
203
189
  # so we need to remove the positional only args from params
204
190
  if positional_only_params:
205
191
  args = removePositonalOnlyFromArgs(args, positional_only_params)
@@ -391,6 +377,7 @@ def process_docstring(app, _type, name, obj, options, lines):
391
377
  """
392
378
  # Use exception as class
393
379
  py2docfx_logger = get_package_logger(__name__)
380
+
394
381
  def check_convert_package_type(obj, _type):
395
382
  if _type == MODULE:
396
383
  filename = getattr(obj, '__file__', None)
@@ -1,24 +1,18 @@
1
1
  import pytest
2
-
3
- from sphinx.testing import restructuredtext
4
- from sphinx.io import SphinxStandaloneReader
5
- from sphinx import addnodes
6
2
  from translator import translator
3
+ from .utils.test_utils import prepare_app_envs, load_rst_transform_to_doctree, do_autodoc
7
4
 
8
- from .utils.test_utils import prepare_app_envs,prepare_refered_objects,load_rst_transform_to_doctree, do_autodoc
9
5
  @pytest.mark.sphinx('dummy', testroot='method-arguments')
10
6
  def test_method_with_three_type_of_arguments(app):
11
7
  # Test data definition
12
8
  objectToGenXml = 'code_with_all_arg_types.TestClass'
13
9
  objectToGenXmlType = 'class'
14
-
15
10
  # Arrange
16
11
  prepare_app_envs(app, objectToGenXml)
17
12
  doctree = load_rst_transform_to_doctree(app, objectToGenXmlType, objectToGenXml)
18
13
 
19
14
  # Act
20
15
  translator(app, '', doctree)
21
-
22
16
  # Assert
23
17
  argumentsDetail = app.env.docfx_yaml_classes[objectToGenXml][1]['syntax']
24
18
  parameters = argumentsDetail.get('parameters', None)
@@ -0,0 +1,120 @@
1
+ import pytest
2
+ import inspect
3
+ from sphinx.config import Config
4
+ from docfx_yaml.process_doctree import (
5
+ getParameterArgs,
6
+ getKeywordOnlyParameters
7
+ )
8
+ from unittest.mock import Mock
9
+ from docfx_yaml.process_doctree import process_docstring
10
+ from sphinx.config import ENUM
11
+
12
+ # Test data for getParameterArgs
13
+ @pytest.mark.parametrize("func, expected_args", [
14
+ (lambda a, b=2, *, c=3, d=4: None, [
15
+ {'id': 'a', 'isRequired': True},
16
+ {'id': 'b', 'defaultValue': '2'}
17
+ ]),
18
+ (lambda x, y, z=5: None, [
19
+ {'id': 'x', 'isRequired': True},
20
+ {'id': 'y', 'isRequired': True},
21
+ {'id': 'z', 'defaultValue': '5'}
22
+ ])
23
+ ])
24
+ def test_getParameterArgs(func, expected_args):
25
+ signature = inspect.signature(func)
26
+ args = getParameterArgs(signature)
27
+ assert args == expected_args
28
+
29
+ # Test data for getKeywordOnlyParameters
30
+ @pytest.mark.parametrize("func, expected_kwonlyargs", [
31
+ (lambda a, b=2, *, c=3, d=4: None, [
32
+ {'id': 'c', 'defaultValue': '3'},
33
+ {'id': 'd', 'defaultValue': '4'}
34
+ ]),
35
+ (lambda x, y, *, z=5: None, [
36
+ {'id': 'z', 'defaultValue': '5'}
37
+ ])
38
+ ])
39
+ def test_getKeywordOnlyParameters(func, expected_kwonlyargs):
40
+ signature = inspect.signature(func)
41
+ kwonlyargs = getKeywordOnlyParameters(signature)
42
+ assert kwonlyargs == expected_kwonlyargs
43
+
44
+
45
+ @pytest.fixture
46
+ def app():
47
+ app = Mock()
48
+ app.config = Config()
49
+ app.config.autoclass_content = 'both'
50
+ app.config.autodoc_functions = True
51
+ app.env = Mock()
52
+ app.env.docfx_yaml_packages = {}
53
+ app.env.docfx_yaml_modules = {}
54
+ app.env.docfx_yaml_classes = {}
55
+ app.env.docfx_yaml_functions = {}
56
+ app.env.docfx_info_uid_types = {}
57
+ return app
58
+
59
+
60
+ def test_process_docstring_class(app):
61
+ class DummyClass:
62
+ """This is a dummy class."""
63
+ def method(self):
64
+ pass
65
+
66
+ process_docstring(app, 'class', 'test_module.DummyClass', DummyClass, {}, [])
67
+
68
+ assert 'test_module.DummyClass' in app.env.docfx_yaml_classes
69
+ assert len(app.env.docfx_yaml_classes['test_module.DummyClass']) == 1
70
+ datam = app.env.docfx_yaml_classes['test_module.DummyClass'][0]
71
+ assert datam['type'] == 'class'
72
+ assert datam['name'] == 'DummyClass'
73
+ assert datam['fullName'] == 'test_module.DummyClass'
74
+
75
+
76
+ def test_process_docstring_function(app):
77
+ def dummy_function():
78
+ """This is a dummy function."""
79
+ pass
80
+
81
+ process_docstring(app, 'function', 'test_module.dummy_function', dummy_function, {}, [])
82
+
83
+ assert 'test_module.dummy_function' in app.env.docfx_yaml_functions
84
+ assert len(app.env.docfx_yaml_functions['test_module.dummy_function']) == 1
85
+ datam = app.env.docfx_yaml_functions['test_module.dummy_function'][0]
86
+ assert datam['type'] == 'function'
87
+ assert datam['name'] == 'dummy_function'
88
+ assert datam['fullName'] == 'test_module.dummy_function'
89
+
90
+
91
+ def test_process_docstring_decorated_method(app):
92
+ class DecoratedClass:
93
+ """This is a decorated class."""
94
+ @staticmethod
95
+ def decorated_method(a, b=2, *, c=3):
96
+ """This is a decorated method."""
97
+ pass
98
+
99
+ process_docstring(app, 'class', 'test_module.DecoratedClass', DecoratedClass, {}, [])
100
+
101
+ assert 'test_module.DecoratedClass' in app.env.docfx_yaml_classes
102
+ assert len(app.env.docfx_yaml_classes['test_module.DecoratedClass']) == 1
103
+ datam = app.env.docfx_yaml_classes['test_module.DecoratedClass'][0]
104
+ assert datam['type'] == 'class'
105
+ assert datam['name'] == 'DecoratedClass'
106
+ assert datam['fullName'] == 'test_module.DecoratedClass'
107
+
108
+ process_docstring(app, 'method', 'test_module.DecoratedClass.decorated_method', DecoratedClass.decorated_method, {}, [])
109
+
110
+ method_syntax_list = [m for m in app.env.docfx_yaml_classes['test_module.DecoratedClass'] if m['name'] == 'decorated_method']
111
+ assert len(method_syntax_list) == 1
112
+ method_syntax = method_syntax_list[0]['syntax']
113
+ assert method_syntax['parameters'] == [
114
+ {'id': 'a', 'isRequired': True},
115
+ {'id': 'b', 'defaultValue': '2'}
116
+ ]
117
+ assert method_syntax['keywordOnlyParameters'] == [
118
+ {'id': 'c', 'defaultValue': '3'}
119
+ ]
120
+ assert 'positionalOnlyParameters' not in method_syntax
@@ -1,5 +1,16 @@
1
+ import warnings
2
+
1
3
  from .compilers.C import msvc
2
4
 
3
5
  __all__ = ["MSVCCompiler"]
4
6
 
5
7
  MSVCCompiler = msvc.Compiler
8
+
9
+
10
+ def __getattr__(name):
11
+ if name == '_get_vc_env':
12
+ warnings.warn(
13
+ "_get_vc_env is private; find an alternative (pypa/distutils#340)"
14
+ )
15
+ return msvc._get_vc_env
16
+ raise AttributeError(name)
@@ -3,40 +3,21 @@
3
3
  Package containing implementation of all the standard Distutils
4
4
  commands."""
5
5
 
6
- from . import (
7
- bdist,
8
- bdist_dumb,
9
- bdist_rpm,
10
- build,
11
- build_clib,
12
- build_ext,
13
- build_py,
14
- build_scripts,
15
- check,
16
- clean,
17
- install,
18
- install_data,
19
- install_headers,
20
- install_lib,
21
- install_scripts,
22
- sdist,
23
- )
24
-
25
6
  __all__ = [
26
- 'bdist',
27
- 'bdist_dumb',
28
- 'bdist_rpm',
29
7
  'build',
30
- 'build_clib',
31
- 'build_ext',
32
8
  'build_py',
9
+ 'build_ext',
10
+ 'build_clib',
33
11
  'build_scripts',
34
- 'check',
35
12
  'clean',
36
13
  'install',
37
- 'install_data',
38
- 'install_headers',
39
14
  'install_lib',
15
+ 'install_headers',
40
16
  'install_scripts',
17
+ 'install_data',
41
18
  'sdist',
19
+ 'bdist',
20
+ 'bdist_dumb',
21
+ 'bdist_rpm',
22
+ 'check',
42
23
  ]
@@ -100,7 +100,7 @@ def _apply_tool_table(dist: Distribution, config: dict, filename: StrPath):
100
100
  pypa_guides = "guides/writing-pyproject-toml/#license-files"
101
101
  SetuptoolsDeprecationWarning.emit(
102
102
  "'tool.setuptools.license-files' is deprecated in favor of "
103
- "'project.license-files'",
103
+ "'project.license-files' (available on setuptools>=77.0.0).",
104
104
  see_url=f"https://packaging.python.org/en/latest/{pypa_guides}",
105
105
  due_date=(2026, 2, 18), # Warning introduced on 2025-02-18
106
106
  )
@@ -211,7 +211,8 @@ def _license(dist: Distribution, val: str | dict, root_dir: StrPath | None):
211
211
  SetuptoolsDeprecationWarning.emit(
212
212
  "`project.license` as a TOML table is deprecated",
213
213
  "Please use a simple string containing a SPDX expression for "
214
- "`project.license`. You can also use `project.license-files`.",
214
+ "`project.license`. You can also use `project.license-files`. "
215
+ "(Both options available on setuptools>=77.0.0).",
215
216
  see_url=f"https://packaging.python.org/en/latest/{pypa_guides}",
216
217
  due_date=(2026, 2, 18), # Introduced on 2025-02-18
217
218
  )
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import functools
3
4
  import io
4
5
  import itertools
5
6
  import numbers
@@ -595,8 +596,8 @@ class Distribution(_Distribution):
595
596
  continue
596
597
 
597
598
  val = parser.get(section, opt)
598
- opt = self.warn_dash_deprecation(opt, section)
599
- opt = self.make_option_lowercase(opt, section)
599
+ opt = self._enforce_underscore(opt, section)
600
+ opt = self._enforce_option_lowercase(opt, section)
600
601
  opt_dict[opt] = (filename, val)
601
602
 
602
603
  # Make the ConfigParser forget everything (so we retain
@@ -621,65 +622,63 @@ class Distribution(_Distribution):
621
622
  except ValueError as e:
622
623
  raise DistutilsOptionError(e) from e
623
624
 
624
- def warn_dash_deprecation(self, opt: str, section: str) -> str:
625
- if section in (
626
- 'options.extras_require',
627
- 'options.data_files',
628
- ):
625
+ def _enforce_underscore(self, opt: str, section: str) -> str:
626
+ if "-" not in opt or self._skip_setupcfg_normalization(section):
629
627
  return opt
630
628
 
631
629
  underscore_opt = opt.replace('-', '_')
632
- commands = list(
633
- itertools.chain(
634
- distutils.command.__all__,
635
- self._setuptools_commands(),
636
- )
630
+ affected = f"(Affected: {self.metadata.name})." if self.metadata.name else ""
631
+ SetuptoolsDeprecationWarning.emit(
632
+ f"Invalid dash-separated key {opt!r} in {section!r} (setup.cfg), "
633
+ f"please use the underscore name {underscore_opt!r} instead.",
634
+ f"""
635
+ Usage of dash-separated {opt!r} will not be supported in future
636
+ versions. Please use the underscore name {underscore_opt!r} instead.
637
+ {affected}
638
+ """,
639
+ see_docs="userguide/declarative_config.html",
640
+ due_date=(2026, 3, 3),
641
+ # Warning initially introduced in 3 Mar 2021
637
642
  )
638
- if (
639
- not section.startswith('options')
640
- and section != 'metadata'
641
- and section not in commands
642
- ):
643
- return underscore_opt
644
-
645
- if '-' in opt:
646
- SetuptoolsDeprecationWarning.emit(
647
- "Invalid dash-separated options",
648
- f"""
649
- Usage of dash-separated {opt!r} will not be supported in future
650
- versions. Please use the underscore name {underscore_opt!r} instead.
651
- """,
652
- see_docs="userguide/declarative_config.html",
653
- due_date=(2025, 3, 3),
654
- # Warning initially introduced in 3 Mar 2021
655
- )
656
643
  return underscore_opt
657
644
 
658
- def _setuptools_commands(self):
659
- try:
660
- entry_points = metadata.distribution('setuptools').entry_points
661
- return {ep.name for ep in entry_points} # Avoid newer API for compatibility
662
- except metadata.PackageNotFoundError:
663
- # during bootstrapping, distribution doesn't exist
664
- return []
665
-
666
- def make_option_lowercase(self, opt: str, section: str) -> str:
667
- if section != 'metadata' or opt.islower():
645
+ def _enforce_option_lowercase(self, opt: str, section: str) -> str:
646
+ if opt.islower() or self._skip_setupcfg_normalization(section):
668
647
  return opt
669
648
 
670
649
  lowercase_opt = opt.lower()
650
+ affected = f"(Affected: {self.metadata.name})." if self.metadata.name else ""
671
651
  SetuptoolsDeprecationWarning.emit(
672
- "Invalid uppercase configuration",
652
+ f"Invalid uppercase key {opt!r} in {section!r} (setup.cfg), "
653
+ f"please use lowercase {lowercase_opt!r} instead.",
673
654
  f"""
674
655
  Usage of uppercase key {opt!r} in {section!r} will not be supported in
675
656
  future versions. Please use lowercase {lowercase_opt!r} instead.
657
+ {affected}
676
658
  """,
677
659
  see_docs="userguide/declarative_config.html",
678
- due_date=(2025, 3, 3),
660
+ due_date=(2026, 3, 3),
679
661
  # Warning initially introduced in 6 Mar 2021
680
662
  )
681
663
  return lowercase_opt
682
664
 
665
+ def _skip_setupcfg_normalization(self, section: str) -> bool:
666
+ skip = (
667
+ 'options.extras_require',
668
+ 'options.data_files',
669
+ 'options.entry_points',
670
+ 'options.package_data',
671
+ 'options.exclude_package_data',
672
+ )
673
+ return section in skip or not self._is_setuptools_section(section)
674
+
675
+ def _is_setuptools_section(self, section: str) -> bool:
676
+ return (
677
+ section == "metadata"
678
+ or section.startswith("options")
679
+ or section in _setuptools_commands()
680
+ )
681
+
683
682
  # FIXME: 'Distribution._set_command_options' is too complex (14)
684
683
  def _set_command_options(self, command_obj, option_dict=None): # noqa: C901
685
684
  """
@@ -1105,6 +1104,18 @@ class Distribution(_Distribution):
1105
1104
  super().run_command(command)
1106
1105
 
1107
1106
 
1107
+ @functools.cache
1108
+ def _setuptools_commands() -> set[str]:
1109
+ try:
1110
+ # Use older API for importlib.metadata compatibility
1111
+ entry_points = metadata.distribution('setuptools').entry_points
1112
+ eps: Iterable[str] = (ep.name for ep in entry_points)
1113
+ except metadata.PackageNotFoundError:
1114
+ # during bootstrapping, distribution doesn't exist
1115
+ eps = []
1116
+ return {*distutils.command.__all__, *eps}
1117
+
1118
+
1108
1119
  class DistDeprecationWarning(SetuptoolsDeprecationWarning):
1109
1120
  """Class for warning about deprecations in dist in
1110
1121
  setuptools. Not ignored by default, unlike DeprecationWarning."""
@@ -1,6 +1,7 @@
1
1
  import configparser
2
2
  import contextlib
3
3
  import inspect
4
+ import re
4
5
  from pathlib import Path
5
6
  from unittest.mock import Mock, patch
6
7
 
@@ -420,36 +421,48 @@ class TestMetadata:
420
421
  with get_dist(tmpdir):
421
422
  pass
422
423
 
423
- @pytest.mark.xfail(reason="#4864")
424
- def test_warn_dash_deprecation(self, tmpdir):
425
- # warn_dash_deprecation() is a method in setuptools.dist
426
- # remove this test and the method when no longer needed
427
- fake_env(
428
- tmpdir,
429
- '[metadata]\n'
430
- 'author-email = test@test.com\n'
431
- 'maintainer_email = foo@foo.com\n',
432
- )
433
- msg = "Usage of dash-separated 'author-email' will not be supported"
434
- with pytest.warns(SetuptoolsDeprecationWarning, match=msg):
435
- with get_dist(tmpdir) as dist:
436
- metadata = dist.metadata
437
-
438
- assert metadata.author_email == 'test@test.com'
439
- assert metadata.maintainer_email == 'foo@foo.com'
440
-
441
- @pytest.mark.xfail(reason="#4864")
442
- def test_make_option_lowercase(self, tmpdir):
443
- # remove this test and the method make_option_lowercase() in setuptools.dist
444
- # when no longer needed
445
- fake_env(tmpdir, '[metadata]\nName = foo\ndescription = Some description\n')
446
- msg = "Usage of uppercase key 'Name' in 'metadata' will not be supported"
447
- with pytest.warns(SetuptoolsDeprecationWarning, match=msg):
448
- with get_dist(tmpdir) as dist:
449
- metadata = dist.metadata
424
+ @pytest.mark.parametrize(
425
+ ("error_msg", "config", "invalid"),
426
+ [
427
+ (
428
+ "Invalid dash-separated key 'author-email' in 'metadata' (setup.cfg)",
429
+ DALS(
430
+ """
431
+ [metadata]
432
+ author-email = test@test.com
433
+ maintainer_email = foo@foo.com
434
+ """
435
+ ),
436
+ {"author-email": "test@test.com"},
437
+ ),
438
+ (
439
+ "Invalid uppercase key 'Name' in 'metadata' (setup.cfg)",
440
+ DALS(
441
+ """
442
+ [metadata]
443
+ Name = foo
444
+ description = Some description
445
+ """
446
+ ),
447
+ {"Name": "foo"},
448
+ ),
449
+ ],
450
+ )
451
+ def test_invalid_options_previously_deprecated(
452
+ self, tmpdir, error_msg, config, invalid
453
+ ):
454
+ # This test and related methods can be removed when no longer needed.
455
+ # Deprecation postponed due to push-back from the community in
456
+ # https://github.com/pypa/setuptools/issues/4910
457
+ fake_env(tmpdir, config)
458
+ with pytest.warns(SetuptoolsDeprecationWarning, match=re.escape(error_msg)):
459
+ dist = get_dist(tmpdir).__enter__()
460
+
461
+ tmpdir.join('setup.cfg').remove()
450
462
 
451
- assert metadata.name == 'foo'
452
- assert metadata.description == 'Some description'
463
+ for field, value in invalid.items():
464
+ attr = field.replace("-", "_").lower()
465
+ assert getattr(dist.metadata, attr) == value
453
466
 
454
467
 
455
468
  class TestOptions:
@@ -54,7 +54,7 @@ EXAMPLES = [
54
54
  ("pyyaml", LATEST), # cython + custom build_ext + custom distclass
55
55
  ("charset-normalizer", LATEST), # uses mypyc, used by aiohttp
56
56
  ("protobuf", LATEST),
57
- ("requests", LATEST),
57
+ # ("requests", LATEST), # XXX: https://github.com/psf/requests/pull/6920
58
58
  ("celery", LATEST),
59
59
  # When adding packages to this list, make sure they expose a `__version__`
60
60
  # attribute, or modify the tests below
@@ -7,4 +7,4 @@
7
7
 
8
8
  # Copyright 2007 Google Inc. All Rights Reserved.
9
9
 
10
- __version__ = '6.30.1'
10
+ __version__ = '6.30.2'
@@ -2,7 +2,7 @@
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # NO CHECKED-IN PROTOBUF GENCODE
4
4
  # source: google/protobuf/any.proto
5
- # Protobuf Python Version: 6.30.1
5
+ # Protobuf Python Version: 6.30.2
6
6
  """Generated protocol buffer code."""
7
7
  from google.protobuf import descriptor as _descriptor
8
8
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -13,7 +13,7 @@ _runtime_version.ValidateProtobufRuntimeVersion(
13
13
  _runtime_version.Domain.PUBLIC,
14
14
  6,
15
15
  30,
16
- 1,
16
+ 2,
17
17
  '',
18
18
  'google/protobuf/any.proto'
19
19
  )
@@ -2,7 +2,7 @@
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # NO CHECKED-IN PROTOBUF GENCODE
4
4
  # source: google/protobuf/api.proto
5
- # Protobuf Python Version: 6.30.1
5
+ # Protobuf Python Version: 6.30.2
6
6
  """Generated protocol buffer code."""
7
7
  from google.protobuf import descriptor as _descriptor
8
8
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -13,7 +13,7 @@ _runtime_version.ValidateProtobufRuntimeVersion(
13
13
  _runtime_version.Domain.PUBLIC,
14
14
  6,
15
15
  30,
16
- 1,
16
+ 2,
17
17
  '',
18
18
  'google/protobuf/api.proto'
19
19
  )
@@ -2,7 +2,7 @@
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # NO CHECKED-IN PROTOBUF GENCODE
4
4
  # source: google/protobuf/compiler/plugin.proto
5
- # Protobuf Python Version: 6.30.1
5
+ # Protobuf Python Version: 6.30.2
6
6
  """Generated protocol buffer code."""
7
7
  from google.protobuf import descriptor as _descriptor
8
8
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -13,7 +13,7 @@ _runtime_version.ValidateProtobufRuntimeVersion(
13
13
  _runtime_version.Domain.PUBLIC,
14
14
  6,
15
15
  30,
16
- 1,
16
+ 2,
17
17
  '',
18
18
  'google/protobuf/compiler/plugin.proto'
19
19
  )
@@ -2,7 +2,7 @@
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # NO CHECKED-IN PROTOBUF GENCODE
4
4
  # source: google/protobuf/descriptor.proto
5
- # Protobuf Python Version: 6.30.1
5
+ # Protobuf Python Version: 6.30.2
6
6
  """Generated protocol buffer code."""
7
7
  from google.protobuf import descriptor as _descriptor
8
8
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -13,7 +13,7 @@ _runtime_version.ValidateProtobufRuntimeVersion(
13
13
  _runtime_version.Domain.PUBLIC,
14
14
  6,
15
15
  30,
16
- 1,
16
+ 2,
17
17
  '',
18
18
  'google/protobuf/descriptor.proto'
19
19
  )
@@ -2,7 +2,7 @@
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # NO CHECKED-IN PROTOBUF GENCODE
4
4
  # source: google/protobuf/duration.proto
5
- # Protobuf Python Version: 6.30.1
5
+ # Protobuf Python Version: 6.30.2
6
6
  """Generated protocol buffer code."""
7
7
  from google.protobuf import descriptor as _descriptor
8
8
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -13,7 +13,7 @@ _runtime_version.ValidateProtobufRuntimeVersion(
13
13
  _runtime_version.Domain.PUBLIC,
14
14
  6,
15
15
  30,
16
- 1,
16
+ 2,
17
17
  '',
18
18
  'google/protobuf/duration.proto'
19
19
  )