We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[FR] Improve setuptools tracebacks for invalid entry points
### setuptools version

65.5.1

### Python version

3.8.13

### OS

macOS 10.15.7

### Additional environment information

macOS 10.15.7
python 3.8.13 installed via pyenv
virtualenv has 
```console
> pip list
Package            Version
------------------ ---------
build              0.9.0
certifi            2022.9.24
charset-normalizer 2.1.1
idna               3.4
importlib-metadata 5.0.0
jaraco.classes     3.2.3
keyring            23.11.0
more-itertools     9.0.0
packaging          21.3
pep517             0.13.0
pip                22.3.1
pyparsing          3.0.9
pyvmomi            7.0.3
requests           2.28.1
setuptools         65.5.1
six                1.16.0
tomli              2.0.1
urllib3            1.26.12
zipp               3.10.0
```
(Top level is requests, pyvmomi, and a build dep of "build" - rest are dependancies)



### Description

Attempting to do a "simple" (what *I* thought was a simple build with "build" package.

My pyproject.toml:
```console

[build-system]
requires = [
    "setuptools",
    "build"
]

build-backend = "setuptools.build_meta"
```


My setup.cfg
```console

[metadata]
name = monitor-vsphere
version = attr: monitor-vsphere.main.__version__

author = Hunter Matthews
author_email = hunter.matthews@nih.gov
description = Query and compare VM's in both NHGRI's vsphere and Device42 systems. Report differences.
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/NHGRI/monitor-vsphere
project_urls =
    Bug Tracker = https://github.com/NHGRI/monitor-vsphere/issues
classifiers =
    Programming Language :: Python :: 3
    Operating System :: OS Independent

[options]
python_requires = >=3.8
#include_package_data = True
package_dir =
    =src
packages = find:
install_requires =
    keyring
    requests
    pyvmomi
zip_safe = False      ## namespace pkgs are not zip safe - probably

[options.packages.find]
where = src

[options.extras_require]
dev = build

[options.entry_points]
console_scripts =
    monitor-vsphere = monitor-vsphere.main:main

```
-----------------------------------------------

I do NOT have a setup.py


My development tree after an unsuccessful build:
> tree
.

├── pyproject.toml
├── setup.cfg
└── src
    ├── monitor-vsphere
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   └── __init__.cpython-38.pyc
    │   ├── auth.py
    │   ├── device42.py
    │   ├── dotdict.py
    │   ├── logs.py
    │   ├── main.py
    │   ├── virtualmachine.py
    │   └── vsphere.py
    └── monitor_vsphere.egg-info
        ├── PKG-INFO
        ├── dependency_links.txt
        └── not-zip-safe

### Expected behavior

Build a sdist and a wheel. 

### How to Reproduce

```console
python -m build
```

My apologies if this something very simple I've missed - the traceback is generic enough (a regex failure) that my google fu was weak on this one. 

I did try downgrading both setuptools  and importlib-metadata a couple of versions (guessing, based on the traceback) but no joy. 

Please let me know if other information is needed.


### Output

```console
> python -m build
* Creating venv isolated environment...
* Installing packages in isolated environment... (build, setuptools)
* Getting build dependencies for sdist...
running egg_info
writing src/monitor_vsphere.egg-info/PKG-INFO
writing dependency_links to src/monitor_vsphere.egg-info/dependency_links.txt
Traceback (most recent call last):
  File "/Users/matthewsht/projects/monitor-vsphere/.direnv/python-3.8.13/lib/python3.8/site-packages/pep517/in_process/_in_process.py", line 351, in <module>
    main()
  File "/Users/matthewsht/projects/monitor-vsphere/.direnv/python-3.8.13/lib/python3.8/site-packages/pep517/in_process/_in_process.py", line 333, in main
    json_out['return_val'] = hook(**hook_input['kwargs'])
  File "/Users/matthewsht/projects/monitor-vsphere/.direnv/python-3.8.13/lib/python3.8/site-packages/pep517/in_process/_in_process.py", line 285, in get_requires_for_build_sdist
    return hook(config_settings)
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/build_meta.py", line 341, in get_requires_for_build_sdist
    return self._get_build_requires(config_settings, requirements=[])
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/build_meta.py", line 320, in _get_build_requires
    self.run_setup()
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/build_meta.py", line 335, in run_setup
    exec(code, locals())
  File "<string>", line 1, in <module>
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/__init__.py", line 87, in setup
    return distutils.core.setup(**attrs)
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 185, in setup
    return run_commands(dist)
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
    dist.run_commands()
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 968, in run_commands
    self.run_command(cmd)
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/dist.py", line 1217, in run_command
    super().run_command(command)
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 987, in run_command
    cmd_obj.run()
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/command/egg_info.py", line 301, in run
    writer(self, ep.name, os.path.join(self.egg_info, ep.name))
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/command/egg_info.py", line 741, in write_entries
    eps = _entry_points.load(cmd.distribution.entry_points)
  File "/Users/matthewsht/.local/pyenv/versions/3.8.13/lib/python3.8/functools.py", line 875, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_entry_points.py", line 51, in load
    return validate(metadata.EntryPoints(groups))
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_entry_points.py", line 39, in validate
    consume(map(ensure_valid, ensure_unique(eps, key=by_group_and_name)))
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_vendor/more_itertools/recipes.py", line 139, in consume
    deque(iterator, maxlen=0)
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_entry_points.py", line 17, in ensure_valid
    ep.extras
  File "/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_vendor/importlib_metadata/__init__.py", line 211, in extras
    return list(re.finditer(r'\w+', match.group('extras') or ''))
AttributeError: 'NoneType' object has no attribute 'group'

ERROR Backend subprocess exited when trying to invoke get_requires_for_build_sdist
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `setuptools/_entry_points.py`
Content:
```
1 import functools
2 import operator
3 import itertools
4 
5 from .extern.jaraco.text import yield_lines
6 from .extern.jaraco.functools import pass_none
7 from ._importlib import metadata
8 from ._itertools import ensure_unique
9 from .extern.more_itertools import consume
10 
11 
12 def ensure_valid(ep):
13     """
14     Exercise one of the dynamic properties to trigger
15     the pattern match.
16     """
17     ep.extras
18 
19 
20 def load_group(value, group):
21     """
22     Given a value of an entry point or series of entry points,
23     return each as an EntryPoint.
24     """
25     # normalize to a single sequence of lines
26     lines = yield_lines(value)
27     text = f'[{group}]\n' + '\n'.join(lines)
28     return metadata.EntryPoints._from_text(text)
29 
30 
31 def by_group_and_name(ep):
32     return ep.group, ep.name
33 
34 
35 def validate(eps: metadata.EntryPoints):
36     """
37     Ensure entry points are unique by group and name and validate each.
38     """
39     consume(map(ensure_valid, ensure_unique(eps, key=by_group_and_name)))
40     return eps
41 
42 
43 @functools.singledispatch
44 def load(eps):
45     """
46     Given a Distribution.entry_points, produce EntryPoints.
47     """
48     groups = itertools.chain.from_iterable(
49         load_group(value, group)
50         for group, value in eps.items())
51     return validate(metadata.EntryPoints(groups))
52 
53 
54 @load.register(str)
55 def _(eps):
56     r"""
57     >>> ep, = load('[console_scripts]\nfoo=bar')
58     >>> ep.group
59     'console_scripts'
60     >>> ep.name
61     'foo'
62     >>> ep.value
63     'bar'
64     """
65     return validate(metadata.EntryPoints(metadata.EntryPoints._from_text(eps)))
66 
67 
68 load.register(type(None), lambda x: x)
69 
70 
71 @pass_none
72 def render(eps: metadata.EntryPoints):
73     by_group = operator.attrgetter('group')
74     groups = itertools.groupby(sorted(eps, key=by_group), by_group)
75 
76     return '\n'.join(
77         f'[{group}]\n{render_items(items)}\n'
78         for group, items in groups
79     )
80 
81 
82 def render_items(eps):
83     return '\n'.join(
84         f'{ep.name} = {ep.value}'
85         for ep in sorted(eps)
86     )
87
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/setuptools/_entry_points.py b/setuptools/_entry_points.py
--- a/setuptools/_entry_points.py
+++ b/setuptools/_entry_points.py
@@ -2,6 +2,7 @@
 import operator
 import itertools
 
+from .errors import OptionError
 from .extern.jaraco.text import yield_lines
 from .extern.jaraco.functools import pass_none
 from ._importlib import metadata
@@ -14,7 +15,14 @@
     Exercise one of the dynamic properties to trigger
     the pattern match.
     """
-    ep.extras
+    try:
+        ep.extras
+    except AttributeError as ex:
+        msg = (
+            f"Problems to parse {ep}.\nPlease ensure entry-point follows the spec: "
+            "https://packaging.python.org/en/latest/specifications/entry-points/"
+        )
+        raise OptionError(msg) from ex
 
 
 def load_group(value, group):

{"golden_diff": "diff --git a/setuptools/_entry_points.py b/setuptools/_entry_points.py\n--- a/setuptools/_entry_points.py\n+++ b/setuptools/_entry_points.py\n@@ -2,6 +2,7 @@\n import operator\n import itertools\n \n+from .errors import OptionError\n from .extern.jaraco.text import yield_lines\n from .extern.jaraco.functools import pass_none\n from ._importlib import metadata\n@@ -14,7 +15,14 @@\n     Exercise one of the dynamic properties to trigger\n     the pattern match.\n     \"\"\"\n-    ep.extras\n+    try:\n+        ep.extras\n+    except AttributeError as ex:\n+        msg = (\n+            f\"Problems to parse {ep}.\\nPlease ensure entry-point follows the spec: \"\n+            \"https://packaging.python.org/en/latest/specifications/entry-points/\"\n+        )\n+        raise OptionError(msg) from ex\n \n \n def load_group(value, group):\n", "issue": "[FR] Improve setuptools tracebacks for invalid entry points\n### setuptools version\r\n\r\n65.5.1\r\n\r\n### Python version\r\n\r\n3.8.13\r\n\r\n### OS\r\n\r\nmacOS 10.15.7\r\n\r\n### Additional environment information\r\n\r\nmacOS 10.15.7\r\npython 3.8.13 installed via pyenv\r\nvirtualenv has \r\n```console\r\n> pip list\r\nPackage            Version\r\n------------------ ---------\r\nbuild              0.9.0\r\ncertifi            2022.9.24\r\ncharset-normalizer 2.1.1\r\nidna               3.4\r\nimportlib-metadata 5.0.0\r\njaraco.classes     3.2.3\r\nkeyring            23.11.0\r\nmore-itertools     9.0.0\r\npackaging          21.3\r\npep517             0.13.0\r\npip                22.3.1\r\npyparsing          3.0.9\r\npyvmomi            7.0.3\r\nrequests           2.28.1\r\nsetuptools         65.5.1\r\nsix                1.16.0\r\ntomli              2.0.1\r\nurllib3            1.26.12\r\nzipp               3.10.0\r\n```\r\n(Top level is requests, pyvmomi, and a build dep of \"build\" - rest are dependancies)\r\n\r\n\r\n\r\n### Description\r\n\r\nAttempting to do a \"simple\" (what *I* thought was a simple build with \"build\" package.\r\n\r\nMy pyproject.toml:\r\n```console\r\n\r\n[build-system]\r\nrequires = [\r\n    \"setuptools\",\r\n    \"build\"\r\n]\r\n\r\nbuild-backend = \"setuptools.build_meta\"\r\n```\r\n\r\n\r\nMy setup.cfg\r\n```console\r\n\r\n[metadata]\r\nname = monitor-vsphere\r\nversion = attr: monitor-vsphere.main.__version__\r\n\r\nauthor = Hunter Matthews\r\nauthor_email = hunter.matthews@nih.gov\r\ndescription = Query and compare VM's in both NHGRI's vsphere and Device42 systems. Report differences.\r\nlong_description = file: README.md\r\nlong_description_content_type = text/markdown\r\nurl = https://github.com/NHGRI/monitor-vsphere\r\nproject_urls =\r\n    Bug Tracker = https://github.com/NHGRI/monitor-vsphere/issues\r\nclassifiers =\r\n    Programming Language :: Python :: 3\r\n    Operating System :: OS Independent\r\n\r\n[options]\r\npython_requires = >=3.8\r\n#include_package_data = True\r\npackage_dir =\r\n    =src\r\npackages = find:\r\ninstall_requires =\r\n    keyring\r\n    requests\r\n    pyvmomi\r\nzip_safe = False      ## namespace pkgs are not zip safe - probably\r\n\r\n[options.packages.find]\r\nwhere = src\r\n\r\n[options.extras_require]\r\ndev = build\r\n\r\n[options.entry_points]\r\nconsole_scripts =\r\n    monitor-vsphere = monitor-vsphere.main:main\r\n\r\n```\r\n-----------------------------------------------\r\n\r\nI do NOT have a setup.py\r\n\r\n\r\nMy development tree after an unsuccessful build:\r\n> tree\r\n.\r\n\r\n\u251c\u2500\u2500 pyproject.toml\r\n\u251c\u2500\u2500 setup.cfg\r\n\u2514\u2500\u2500 src\r\n    \u251c\u2500\u2500 monitor-vsphere\r\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 __init__.py\r\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 __pycache__\r\n    \u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 __init__.cpython-38.pyc\r\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 auth.py\r\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 device42.py\r\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 dotdict.py\r\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 logs.py\r\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 main.py\r\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 virtualmachine.py\r\n    \u2502\u00a0\u00a0 \u2514\u2500\u2500 vsphere.py\r\n    \u2514\u2500\u2500 monitor_vsphere.egg-info\r\n        \u251c\u2500\u2500 PKG-INFO\r\n        \u251c\u2500\u2500 dependency_links.txt\r\n        \u2514\u2500\u2500 not-zip-safe\r\n\r\n### Expected behavior\r\n\r\nBuild a sdist and a wheel. \r\n\r\n### How to Reproduce\r\n\r\n```console\r\npython -m build\r\n```\r\n\r\nMy apologies if this something very simple I've missed - the traceback is generic enough (a regex failure) that my google fu was weak on this one. \r\n\r\nI did try downgrading both setuptools  and importlib-metadata a couple of versions (guessing, based on the traceback) but no joy. \r\n\r\nPlease let me know if other information is needed.\r\n\r\n\r\n### Output\r\n\r\n```console\r\n> python -m build\r\n* Creating venv isolated environment...\r\n* Installing packages in isolated environment... (build, setuptools)\r\n* Getting build dependencies for sdist...\r\nrunning egg_info\r\nwriting src/monitor_vsphere.egg-info/PKG-INFO\r\nwriting dependency_links to src/monitor_vsphere.egg-info/dependency_links.txt\r\nTraceback (most recent call last):\r\n  File \"/Users/matthewsht/projects/monitor-vsphere/.direnv/python-3.8.13/lib/python3.8/site-packages/pep517/in_process/_in_process.py\", line 351, in <module>\r\n    main()\r\n  File \"/Users/matthewsht/projects/monitor-vsphere/.direnv/python-3.8.13/lib/python3.8/site-packages/pep517/in_process/_in_process.py\", line 333, in main\r\n    json_out['return_val'] = hook(**hook_input['kwargs'])\r\n  File \"/Users/matthewsht/projects/monitor-vsphere/.direnv/python-3.8.13/lib/python3.8/site-packages/pep517/in_process/_in_process.py\", line 285, in get_requires_for_build_sdist\r\n    return hook(config_settings)\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/build_meta.py\", line 341, in get_requires_for_build_sdist\r\n    return self._get_build_requires(config_settings, requirements=[])\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/build_meta.py\", line 320, in _get_build_requires\r\n    self.run_setup()\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/build_meta.py\", line 335, in run_setup\r\n    exec(code, locals())\r\n  File \"<string>\", line 1, in <module>\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/__init__.py\", line 87, in setup\r\n    return distutils.core.setup(**attrs)\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_distutils/core.py\", line 185, in setup\r\n    return run_commands(dist)\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_distutils/core.py\", line 201, in run_commands\r\n    dist.run_commands()\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_distutils/dist.py\", line 968, in run_commands\r\n    self.run_command(cmd)\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/dist.py\", line 1217, in run_command\r\n    super().run_command(command)\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_distutils/dist.py\", line 987, in run_command\r\n    cmd_obj.run()\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/command/egg_info.py\", line 301, in run\r\n    writer(self, ep.name, os.path.join(self.egg_info, ep.name))\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/command/egg_info.py\", line 741, in write_entries\r\n    eps = _entry_points.load(cmd.distribution.entry_points)\r\n  File \"/Users/matthewsht/.local/pyenv/versions/3.8.13/lib/python3.8/functools.py\", line 875, in wrapper\r\n    return dispatch(args[0].__class__)(*args, **kw)\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_entry_points.py\", line 51, in load\r\n    return validate(metadata.EntryPoints(groups))\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_entry_points.py\", line 39, in validate\r\n    consume(map(ensure_valid, ensure_unique(eps, key=by_group_and_name)))\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_vendor/more_itertools/recipes.py\", line 139, in consume\r\n    deque(iterator, maxlen=0)\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_entry_points.py\", line 17, in ensure_valid\r\n    ep.extras\r\n  File \"/private/var/folders/kg/ylmhpwmn3hb2bdlwl84t6c989ztfk2/T/build-env-vqmomun4/lib/python3.8/site-packages/setuptools/_vendor/importlib_metadata/__init__.py\", line 211, in extras\r\n    return list(re.finditer(r'\\w+', match.group('extras') or ''))\r\nAttributeError: 'NoneType' object has no attribute 'group'\r\n\r\nERROR Backend subprocess exited when trying to invoke get_requires_for_build_sdist\r\n```\r\n\n", "before_files": [{"content": "import functools\nimport operator\nimport itertools\n\nfrom .extern.jaraco.text import yield_lines\nfrom .extern.jaraco.functools import pass_none\nfrom ._importlib import metadata\nfrom ._itertools import ensure_unique\nfrom .extern.more_itertools import consume\n\n\ndef ensure_valid(ep):\n    \"\"\"\n    Exercise one of the dynamic properties to trigger\n    the pattern match.\n    \"\"\"\n    ep.extras\n\n\ndef load_group(value, group):\n    \"\"\"\n    Given a value of an entry point or series of entry points,\n    return each as an EntryPoint.\n    \"\"\"\n    # normalize to a single sequence of lines\n    lines = yield_lines(value)\n    text = f'[{group}]\\n' + '\\n'.join(lines)\n    return metadata.EntryPoints._from_text(text)\n\n\ndef by_group_and_name(ep):\n    return ep.group, ep.name\n\n\ndef validate(eps: metadata.EntryPoints):\n    \"\"\"\n    Ensure entry points are unique by group and name and validate each.\n    \"\"\"\n    consume(map(ensure_valid, ensure_unique(eps, key=by_group_and_name)))\n    return eps\n\n\n@functools.singledispatch\ndef load(eps):\n    \"\"\"\n    Given a Distribution.entry_points, produce EntryPoints.\n    \"\"\"\n    groups = itertools.chain.from_iterable(\n        load_group(value, group)\n        for group, value in eps.items())\n    return validate(metadata.EntryPoints(groups))\n\n\n@load.register(str)\ndef _(eps):\n    r\"\"\"\n    >>> ep, = load('[console_scripts]\\nfoo=bar')\n    >>> ep.group\n    'console_scripts'\n    >>> ep.name\n    'foo'\n    >>> ep.value\n    'bar'\n    \"\"\"\n    return validate(metadata.EntryPoints(metadata.EntryPoints._from_text(eps)))\n\n\nload.register(type(None), lambda x: x)\n\n\n@pass_none\ndef render(eps: metadata.EntryPoints):\n    by_group = operator.attrgetter('group')\n    groups = itertools.groupby(sorted(eps, key=by_group), by_group)\n\n    return '\\n'.join(\n        f'[{group}]\\n{render_items(items)}\\n'\n        for group, items in groups\n    )\n\n\ndef render_items(eps):\n    return '\\n'.join(\n        f'{ep.name} = {ep.value}'\n        for ep in sorted(eps)\n    )\n", "path": "setuptools/_entry_points.py"}], "after_files": [{"content": "import functools\nimport operator\nimport itertools\n\nfrom .errors import OptionError\nfrom .extern.jaraco.text import yield_lines\nfrom .extern.jaraco.functools import pass_none\nfrom ._importlib import metadata\nfrom ._itertools import ensure_unique\nfrom .extern.more_itertools import consume\n\n\ndef ensure_valid(ep):\n    \"\"\"\n    Exercise one of the dynamic properties to trigger\n    the pattern match.\n    \"\"\"\n    try:\n        ep.extras\n    except AttributeError as ex:\n        msg = (\n            f\"Problems to parse {ep}.\\nPlease ensure entry-point follows the spec: \"\n            \"https://packaging.python.org/en/latest/specifications/entry-points/\"\n        )\n        raise OptionError(msg) from ex\n\n\ndef load_group(value, group):\n    \"\"\"\n    Given a value of an entry point or series of entry points,\n    return each as an EntryPoint.\n    \"\"\"\n    # normalize to a single sequence of lines\n    lines = yield_lines(value)\n    text = f'[{group}]\\n' + '\\n'.join(lines)\n    return metadata.EntryPoints._from_text(text)\n\n\ndef by_group_and_name(ep):\n    return ep.group, ep.name\n\n\ndef validate(eps: metadata.EntryPoints):\n    \"\"\"\n    Ensure entry points are unique by group and name and validate each.\n    \"\"\"\n    consume(map(ensure_valid, ensure_unique(eps, key=by_group_and_name)))\n    return eps\n\n\n@functools.singledispatch\ndef load(eps):\n    \"\"\"\n    Given a Distribution.entry_points, produce EntryPoints.\n    \"\"\"\n    groups = itertools.chain.from_iterable(\n        load_group(value, group)\n        for group, value in eps.items())\n    return validate(metadata.EntryPoints(groups))\n\n\n@load.register(str)\ndef _(eps):\n    r\"\"\"\n    >>> ep, = load('[console_scripts]\\nfoo=bar')\n    >>> ep.group\n    'console_scripts'\n    >>> ep.name\n    'foo'\n    >>> ep.value\n    'bar'\n    \"\"\"\n    return validate(metadata.EntryPoints(metadata.EntryPoints._from_text(eps)))\n\n\nload.register(type(None), lambda x: x)\n\n\n@pass_none\ndef render(eps: metadata.EntryPoints):\n    by_group = operator.attrgetter('group')\n    groups = itertools.groupby(sorted(eps, key=by_group), by_group)\n\n    return '\\n'.join(\n        f'[{group}]\\n{render_items(items)}\\n'\n        for group, items in groups\n    )\n\n\ndef render_items(eps):\n    return '\\n'.join(\n        f'{ep.name} = {ep.value}'\n        for ep in sorted(eps)\n    )\n", "path": "setuptools/_entry_points.py"}]}